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

Только 8разница между 'Просто' и 'чистый'

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

Только 8

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

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

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

Не удалось соответствовать типу '[]' с 'Maybe'

Ожидаемый тип: Может б

Фактический тип: [б]

Во втором аргумент '(< *>)', а именно '[0 .. 10]'

В выражении : Просто (* 3) < *> [0 .. 10]

В уравнении для него '': это = Just (* 3) < *> [0 .. 10]

При являются pure и Just взаимозаменяемыми, и когда они отличаются?

ответ

10

pure является перегруженной операцией. Он определен для всех типов, которые реализуют класс Applicative. Один из типов, который делает это: Maybe. Таким образом, pure в этом контексте совпадает с Just. Но есть и другие типы, которые также реализуют Applicative, такие как [] (списки). В этом случае pure означает singleton (т. Е. Функция, которая принимает одно значение и возвращает одноэлементный список, который содержит это значение). Так

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

на самом деле означает:

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

и не

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

В этом последнем примере вы пытаетесь смешать списки с maybes именно поэтому GHC отвергает его. В общем, haskell определяет, что такое точный смысл pure на основе контекста, например. если вы попытаетесь использовать его с maybes, он будет интерпретировать его как Just, если вы используете его со списками, интерпретируйте его как singleton.

6

pure функция возвращает значение полиморфного:

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

Для Maybe, pure просто определяется как Just:

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

Другие типы предоставляют различные определения; В качестве примера, он определен для списков, как

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

Задания типа для возвращаемого значения говорит Haskell, который Applicative экземпляра, используемый для определения pure.

Prelude> pure "foo" :: [[Char]] 
["foo"] 
Prelude> pure "foo" :: Maybe [Char] 
Just "foo" 

В дополнение к предоставлению явного типа, Haskell может вывести, какой тип использовать базу, как используется значение. Например, (<*> [1..5]) :: (Num a, Enum a) => [a -> b] -> [b], поэтому в pure (+3) <*> [1..5] мы знаем, что pure (+3) должен иметь тип [a -> b]. Аналогично, в pure (+3) <*> Just 5 мы знаем, что pure (+3) должен иметь тип Maybe (a->b).

В общем, в любом выражении pure f <*> g, тип g определит, для какого типа значения необходимо вернуть pure f.