8
votes

Déterminez si une liste de fichiers existe dans HASKELLL

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)


2 commentaires

Il convient de noter que replier (&&) true 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.


3 Réponses :


15
votes

Vous avez raison, votre code ne fonctionne pas car Carte FichiersFileExist renvoie une liste de io bool s au lieu de bool . Pour résoudre ce problème, vous pouvez utiliser mapm au lieu de mapper , qui vous donnera un io [bo] . Vous pouvez décompresser qui en utilisant >>> = ou <- à l'intérieur d'un do -block puis utilisez plier (&&) sur le déballé [bool] et retour qui. Le résultat sera un io bool . Comme ceci: xxx

ou à l'aide de la notation: xxx

ou en utilisant liftm de Contrôle. Monad : xxx

ou en utilisant <$> à partir de contrôler.aplicatif : < Pré> xxx


2 commentaires

N'oubliez pas replier (&&) true == et (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 dans le contrôler.monad.loops module. Avec cette fonction, allfilespresent = Allm ne fasse-il



6
votes

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.

Vous êtes sur la droite Suivre avec 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> xxx pré>

ou, car vous utilisez simplement une séquence / map, le mapm code> Fonction d'aide: P>

allFilesPresent :: [String] -> IO Bool
allFilesPresent = fmap and . mapM doesFileExist


3 commentaires

Je pense que vous voulez dire allfilespresent = fmap et. mapm ne fasse pas


Il n'est pas précis de dire qu'un io t est un t qui dépend du monde. C'est une recette pour obtenir un t , 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 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.



6
votes

Notez que si vous utilisez la séquence code> ou code> ou 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: xxx pré>

ou équivalent en utilisant MONAD-LOOPS Paquet : P>

import System.Directory
import Control.Monad.Loops

allFilesPresent :: [FilePath] -> IO Bool
allFilesPresent = allM doesFileExist


0 commentaires