Les autres réponses sont correctes, mais je me demande si ils ne sont pas tout à fait ce que vous avez besoin... je vais essayer de garder ce aussi simple que possible, à seulement deux points:
Point 1. return
n'est pas quelque chose de spécial dans le langage Haskell. Ce n'est pas un mot clé, et ce n'est pas sucre syntaxique pour quelque chose d'autre. C'est juste une fonction qui fait partie de l' Monad
typeclass. Sa signature est simplement:
return :: a -> m a
où m
est selon la monade, nous parlons à la fois. Il prend un "pur" de la valeur et de la confiture dans votre monade. (Soit dit en passant, il y a une autre fonction appelée pure
qui est en fait un synonyme return
... j'aime mieux parce que le nom est plus évident!) De toute façon, si m
s'agit de la liste de l'errance, alors return
a ce type:
return :: a -> [a]
Si cela peut aider, vous pouvez penser que le type synonyme type List a = [a]
, ce qui pourrait le rendre un peu plus évident que l' List
est la chose que nous sommes en remplaçant d' m
. De toute façon, si vous alliez mettre en oeuvre return
vous-même, le seul moyen raisonnable que vous mettriez c'est en prenant une certaine valeur (quel que soit le type a
) et en la collant dans une liste par lui-même:
return a = [a]
Donc, je peux dire return 1
dans la liste monade, et je vais tomber [1]
. Je peux dire la même chose return [1, 2, 3]
et je vais tomber [[1, 2, 3]]
.
Point 2. IO
est une monade, mais pas toutes les monades sont IO
. De nombreux Haskell tutoriels semble faire un amalgame entre les deux sujets en grande partie pour des raisons historiques (d'ailleurs, la même confusion des raisons historiques qui ont conduit à l' return
d'être si mal nommée). Il semble que vous pourriez avoir quelques (compréhensible) de la confusion autour de cela.
Dans votre code, vous êtes dans la liste monade parce que vous avez écrit do x <- [1, 2]
. Si, au contraire, vous l'aviez écrit, do x <- getLine
par exemple, vous seriez dans l' IO
monade (parce qu' getLine
retours IO String
). De toute façon, vous êtes dans la liste de l'errance, de sorte que vous obtenez de la liste de définition de l' return
décrit ci-dessus. Vous bénéficiez également de la liste de définition de l' >>=
, ce qui est tout a basculé version) concatMap
, défini comme suit:
concatMap :: (a -> [b]) -> [a] -> [b]
concatMap f xs = concat (map f xs)
Les autres réponses assez bien en avoir à partir d'ici :) je sais que je ne réponds pas directement à votre question, mais je suis en espérant que ces deux points au lieu adressé des choses fondamentales que vous pourriez avoir de la confusion.