6
votes

Déballer une monade

Compte tenu du programme ci-dessous, j'ai des problèmes liés à des monads.

***************
*** 27,30 ****
    csv_raw <- slurp csv_filename
    let csv_data = parseCSV csv_filename csv_raw

!   printCSV csv_data -- unable to compile. 
\ No newline at end of file
--- 27,35 ----
    csv_raw <- slurp csv_filename
    let csv_data = parseCSV csv_filename csv_raw

!   case csv_data of 
!     Left error -> putStrLn $ show error
!     Right csv_data -> putStrLn $ printCSV csv_data
!     
!   putStrLn "done"
!       


4 commentaires

La question ne semble avoir rien à voir avec les monades. :)


@Rotsor J'allais juste poster une réponse de commentaire, mais elle a ballonné dans une réponse. La question est un peu Sorta est sur les monades, mais pas vraiment.


Paul, n'est-ce pas le problème le mauvais nom attribué printcsv :: csv -> chaîne ? C'est une fonction pure, pas une fonction d'un type IO. Si j'écris putstrln $ printcsv csv_data pour la dernière ligne, il compile.


@Applicatif: Ouais, j'ai eu un coup de pied par le mauvais nom. : - /


3 Réponses :


7
votes

Utilisez case code>.

main = do
    ...
    either ({- error condition function -}) printCSV csv_data


0 commentaires

17
votes

Concernant les monads:

Oui, Un est une monade. Donc, simplifier le problème, vous demandez essentiellement cela: xxx

Comment définissez-vous magicmontaunwrap ? Eh bien, vous voyez, c'est différent pour chaque monade. Chacun a besoin de son propre imprimé. Beaucoup d'entre eux ont le mot "exécuté" en eux, par exemple, runst , runcont ou runeval . Cependant, pour certaines monades, il pourrait ne pas être prudent de les déboucher (d'où la nécessité de différer les déboucheurs différents).

Une implémentation pour les listes serait tête . Mais que si la liste est vide? Un indolpeur pour peut-être est iSJust , mais si c'est si c'est rien ?

De même, le débiteur pour le monade serait quelque chose comme: xxx

mais cette décalage n'est pas en sécurité: que si vous aviez un gauche la valeur? (La gauche représente généralement un état d'erreur, dans votre cas, une erreur d'analyse). Donc, la meilleure façon d'agir sur une valeur Il est d'utiliser la fonction ou d'autre utiliser une instruction de cas correspondant droit et Laissé , comme l'illustre Daniel Wagner.

tl; dr : il n'y a pas magicmontaunwrap . Si vous êtes à l'intérieur de cette même monade, vous pouvez utiliser <- , mais pour extraire vraiment la valeur d'une monade ... Eh bien ... comment vous faites cela dépend de quelle monade vous traitez avec.


3 commentaires

Il y a avec th, quelqu'un a affiché une implémentation d'un monad m => m a -> A . Link: blog.sigfpe.com/2009/01/Rewriting- Monadic-expressions-with.h tml


@monadic: Cette technique est intelligente, mais cela a un problème. Il vous permet seulement d'utiliser extraire dans une épissure de haskell, qui est interprétée alors comme une monade. Il vous donne essentiellement une fantaisie (>> =) , qui pourrait être attendue car extrait est simplement remplacé par joindre .


@Dan: intéressant. Je vois ton point et ça cohéronne mieux dans mon esprit quand je vois ce qui se passe.



3
votes

Vous devez désapprendre ce que vous avez appris. em> p>

Maître Yoda. P>

au lieu de penser ou de rechercher des moyens de "libérer", "libérer", "libérer", "déballer" ou "extraire" des valeurs de haskell normales des contextes centrés sur effet (généralement monadiques), apprenez à utiliser un des caractéristiques plus distinctives de Haskell - Les fonctions sont valeurs de première classe em>: p>

  • Vous pouvez utiliser des fonctions telles que des valeurs d'autres types par exemple. Comme bool code>, char code>, int code>, integer code> etc: p>

    do     .
           .
           .
       x <- this_M
       y <- that_M
       z <- other_M
       let val =  calculate x y z
           .
           .
           .
    


2 commentaires

"Tout est meilleur avec faire ". :)


... y compris sh et c ? ;-)