2016-09-13 2 views
6
Just (+) <*> Just 3 <*> Just 5 

Juste 8différence entre 'juste' et 'pur'

pure (+) <*> Just 3 <*> Just 5 

Juste 8

pure (*3) <*> [0..10] 

[0,3,6, 9,12,15,18,21,24,27,30]

Just (*3) <*> [0..10] 

Impossible type de correspondance '[]' avec 'Maybe'

Type attendu: Peut-être que b

type réel: [b]

Dans la seconde argument de '(< *>)', à savoir '[0 .. 10]'

Dans l'expression : Just (* 3) < *> [0 .. 10]

Dans une équation pour 'il': it = Just (* 3) < *> [0 .. 10]

Lorsque sont pure et Just interchangeables et quand sont-ils différents?

Répondre

10

pure est une opération surchargée. Il est défini pour tous les types qui implémentent la classe Applicative. Un des types qui font cela est Maybe. Donc pure dans ce contexte est le même que Just. Mais il existe d'autres types qui implémentent également Applicative tels que [] (listes). Dans ce cas, pure signifie singleton (c'est-à-dire la fonction qui prend une seule valeur et renvoie la liste d'un élément qui contient cette valeur). Alors

pure (*3) <*> [0..10] 

signifie vraiment:

[(*3)] <*> [0..10] 

et non

Just (*3) <*> [0..10] 

Dans ce dernier exemple, vous essayez de mélanger des listes avec maybes qui est la raison pour laquelle GHC rejette. En général, haskell détermine quelle est la signification exacte de pure en fonction du contexte, par ex. Si vous essayez de l'utiliser avec maybes, il l'interprétera comme Just, si vous l'utilisez avec des listes l'interpréter comme singleton.

6

La fonction retourne une valeur pure polymorphe:

Prelude> :t pure "foo" 
pure "foo" :: Applicative f => f [Char] 

Pour Maybe, pure est simplement définie comme étant Just:

instance Applicative Maybe where 
    pure = Just 
    -- ... 

D'autres types fournissent des définitions différentes; à titre d'exemple, il est défini comme pour les listes

instance Applicative [] where 
    pure x = [x] 
    -- ... 

Spécification d'un type pour la valeur de retour indique Haskell qui Applicative par exemple à utiliser pour la définition de pure. En plus de fournir un type explicite, Haskell peut déduire quel type de base utiliser sur la façon dont la valeur est utilisée. Par exemple, (<*> [1..5]) :: (Num a, Enum a) => [a -> b] -> [b], donc dans pure (+3) <*> [1..5], nous savons que pure (+3) doit avoir le type [a -> b]. De même, dans pure (+3) <*> Just 5, nous savons que pure (+3) doit avoir le type Maybe (a->b).

En général, dans toute expression pure f <*> g, le type de g déterminera quel type de valeur pure f doit retourner.