2011-10-14 6 views
2

Je suis en train de travailler sur "Écris toi-même un interpréteur de schéma en 48 heures" et un exercice consiste à écrire une fonction en utilisant la notation "do". Ceci est la fonction:Comment écrire ceci en notation Do?

parseNumber :: Parser LispVal 
parseNumber = liftM (Number . read) $ many1 digit 

J'ai essayé ce qui suit, mais cela ne fonctionne pas:

parseNumber2 :: Parser LispVal 
parseNumber2 = do digits <- many1 digit 
        return $ liftM $ (Number . read) digits 

Peu importe. J'ai indenté le code incorrectement

+0

Le type de 'liftM' est' (Monad m) => (a -> b) -> ma -> mb'. Dans ce cas, 'liftM' est' fmap' dans la monade 'Parser'. Mais '(nombre.numéros) digits' n'est pas une valeur monadique, vous rencontrez donc une erreur de type (la raison 1:' (nombre. Read) digits' n'est pas une fonction, mais est utilisée comme une fonction, raison 2: '(Nombre.lit) digits' n'est pas une valeur monadique, donc il n'a pas le type' ma' pour un monad 'm'). Cependant, 'return (Number (read (digits)))' utilisé sans 'liftM' est une valeur monadique, et équivalent (lorsqu'il est placé sur la dernière ligne) à la définition d'origine. – danportin

Répondre

6

Une fois que vous avez déballé digits, vous n'avez plus besoin du liftM. Il est donc juste:

return $ Number $ read digits 
4

j'ai sauté sur le canal IRC#haskell et demandé lambdabot:

11:25 < dmwit> ?src liftM 
11:25 < lambdabot> liftM f m1 = do { x1 <- m1; return (f x1) } 
11:27 < dmwit> ?src ($) 
11:27 < lambdabot> f $ x = f x 

(Si vous ne voulez pas demander lambdabot, vous pouvez également demander Hoogle et cliquez sur la source . lien dans la documentation)

donc, nous allons Remplissons f et m1:

liftM (Number . read) $ many1 digit 
    ={definition of ($)} 
liftM (Number . read) (many1 digit) 
    ={definition of liftM} 
do { x1 <- (many1 digit); return ((Number . read) x1) } 
    ={expand to layout form, eliminate redundant parentheses} 
do 
    x1 <- many1 digit 
    return ((Number . read) x1) 

Vous pouvez écrire une demi-douzaine de variations de ce de différentes esthétiques syntaxique, mais voici mon préféré, après avoir développé les définitions de (.) et ($) quelques fois:

={definitions of (.) and ($)} 
do 
    x1 <- many1 digit 
    return . Number . read $ x1 
+0

Je dois aimer lambdabot. <3 –