Vous rendez la vie difficile en programmant d'une manière absolument inutile. Vous programmez dans la belle langue Haskell et vous cherchez une construction goto
!
Pourquoi ne pas simplement import Control.Applicative (<$>)
et écrire
readAndChange' = writeFile "couples.txt" =<<
unlines.map (show.extractNameAndId).lines <$> readFile "deletedId.csv"
(Eh oui, c'est presque en une ligne. Il est dans un style propre et fonctionnel et épuré par la mécanique de la lecture et des lignes d'écriture. Autant que possible du le traitement se fait dans le code pur, seule entrée et de sortie sont basés-IO)
Explication:.
ici unlines.map (show.extractNameAndId).lines
traite votre entrée en coupant i t en lignes, en appliquant extractNameAndId
puis show
à chacun en utilisant map
, puis en les rejoignant à nouveau avec unlines
.
unlines.map (show.extractNameAndId).lines <$> readFile "deletedId.csv"
va lire le fichier et appliquer la fonction de traitement. <$>
est une syntaxe agréable pour fmap
.
writeFile "couples.txt" =<< getanswer
est la même que getanswer >>= writeFile "couples.txt"
- obtenir la réponse comme ci-dessus puis l'écrire dans le fichier.
Essayez d'écrire greet xs = "hello " ++ xs
puis à ghci faire ce pour le plaisir
greet "Jane" -- apply your pure function purely
greet $ "Jane" -- apply it purely again
greet <$> ["Jane","Craig","Brian"] -- apply your function on something that produces three names
greet <$> Just "Jane" -- apply your function on something that might have a name
greet <$> Nothing -- apply your function on something that might have a name
greet <$> getLine -- apply your function to whatever you type in
greet <$> readFile "deletedId.csv" -- apply your function to your file
le dernier est comment nous avons utilisé <$>
dans readAndChange
. S'il y a beaucoup de données dans deletedId.csv vous allez manquer le bonjour, mais bien sûr, vous pouvez faire
greet <$> readFile "deletedId.csv" >>= writeFile "hi.txt"
take 4.lines <$> readFile "hi.txt"
pour voir les 4 premières lignes.
Donc $
vous permet d'utiliser votre fonction sur les arguments que vous avez donnés. greet :: String -> String
donc si vous écrivez greet $ person
, le person
doit être de type String
, alors que si vous écrivez greet <$> someone
, le someone
peut être quelque chose qui produit une String
- une liste de chaînes, une IO String
, un Maybe String
. Techniquement, someone :: Applicative f => f String
, mais vous devriez d'abord lire sur les classes de type et les foncteurs applicatifs. Vous apprendre un Haskell pour le grand bien est une excellente ressource.
Pour encore plus de plaisir, si vous avez une fonction avec plus d'un argument, vous pouvez toujours utiliser le joli style Applicative.
insult :: String -> String -> String
insult a b = a ++ ", you're almost as ugly as " ++ b
Essayez
insult "Fred" "Barney"
insult "Fred" $ "Barney"
insult <$> ["Fred","Barney"] <*> ["Wilma","Betty"]
insult <$> Just "Fred" <*> Nothing
insult <$> Just "Fred" <*> Just "Wilma"
insult <$> readFile "someone.txt" <*> readFile "someoneElse.txt"
Ici vous utilisez <$>
après la fonction et <*>
entre les arguments dont il a besoin. Comment cela fonctionne est un peu hallucinant au premier abord, mais c'est le style le plus fonctionnel de l'écriture efficace des calculs.
Prochaine lecture sur les foncteurs applicatifs. Ils sont super.
http://learnyouahaskell.com/functors-applicative-functors-and-monoids
http://en.wikibooks.org/wiki/Haskell/Applicative_Functors
Incroyable :) Comme vous pouvez le deviner je suis un débutant Haskell; Pouvez-vous s'il vous plaît m'expliquer s'il y a une différence entre '$' et '<$>'? – Aslan986
@ Aslan986 J'ai ajouté un peu plus maintenant. – AndrewC
Impossible de ne pas accepter votre réponse. Merci beaucoup Andrew. – Aslan986