Je suis un débutant, et les monades m'ont totalement confus. Compte tenu d'une liste de noms de fichiers, j'aimerais savoir si tous les fichiers existent.
Généralement, j'aimerais faire: P>
import System.Directory allFilesPresent files = foldr (&&) True (map doesFileExist files)
3 Réponses :
Vous avez raison, votre code ne fonctionne pas car ou à l'aide de la notation: p> ou en utilisant ou en utilisant Carte FichiersFileExist code> renvoie une liste de
io bool code> s au lieu de
bool code>. Pour résoudre ce problème, vous pouvez utiliser
mapm code> au lieu de
mapper code>, qui vous donnera un
io [bo] code>. Vous pouvez décompresser qui en utilisant
>>> = code> ou
<- code> à l'intérieur d'un
do code> -block puis utilisez
plier (&&) Code> sur le déballé
[bool] code> et
retour code> qui. Le résultat sera un
io bool code>. Comme ceci:
liftm code> de
Contrôle. Monad code>: p>
<$> code> à partir de
contrôler.aplicatif p>: p> < Pré> xxx pré> p>
N'oubliez pas replier (&&) true == et code> (ou assez proche de ce cas d'utilisation)
Ou si vous êtes confortable Installation de bibliothèques HASKELLL, la bibliothèque de monad-loops a une fonction allm :: monad m => (a -> m bool) -> [a] -> m bool code> dans le
contrôler.monad.loops code> module. Avec cette fonction,
allfilespresent = Allm ne fasse-il code>
Vous êtes sur la droite Suivre avec ou, car vous utilisez simplement une séquence / map, le fesfileeexist "foo.txt" code> est un
io bool code>, ce qui signifie que son résultat dépend de l'état du monde extérieur.
Carte FichiersFileExist code> - Cette expression retournera
[io bool] code> ou une liste des expressions dépendantes du monde. Ce qui est réellement nécessaire, c'est une expression
io code> contenant une liste de bools. Vous pouvez obtenir ceci à l'aide de la séquence
code>: p>
mapm code> Fonction d'aide: P>
allFilesPresent :: [String] -> IO Bool
allFilesPresent = fmap and . mapM doesFileExist
Je pense que vous voulez dire allfilespresent = fmap et. mapm ne fasse pas code>
Il n'est pas précis de dire qu'un io t code> est un
t code> qui dépend du monde. C'est une recette pour obtenir un
t code>, qui pourrait être exécutée plus d'une fois et produire un résultat différent à chaque fois. Les recettes et les gâteaux sont des types de choses totalement différents.
@keegan: a accepté, et d'élaborer sur cette métaphore, le produit final de exécutant i> une recette de gâteau est la chose que j'appellerais un gâteau qui dépend de l'état précédent du monde. D'une recette donnée (IO Cake), de nombreux gâteaux peuvent être créés.
Notez que si vous utilisez la séquence code> ou code> ou ou équivalent en utilisant MONAD-LOOPS Paquet : P> mapm code>, vous choisissez de ne pas court-circuiter; Même si l'un des fichiers s'avère pas pour exister, vous vérifiez toujours le reste des fichiers d'existence. Si vous souhaitez court-circuiter, les travaux suivants:
import System.Directory
import Control.Monad.Loops
allFilesPresent :: [FilePath] -> IO Bool
allFilesPresent = allM doesFileExist
Il convient de noter que
replier (&&) true code> est la fonction prélude.et.
Je suggère fortement de lire apprenouahakell.com/input-and-output Vous pouvez ensuite lire une partie de la Autres chapitres sur les foncteurs, applicatifs, monoïdes et monads. Introduction très douce et progressive à ces sujets.