Я недавно играл с Монад в Хаскеле (все еще относительный новичок во всем этом).Я столкнулся с некоторым интересным поведением (или, по крайней мере, мне интересным) с Identity Monad
.
Если я напишу следующую функцию:
let f = \x -> Identity 2 >>= \y -> x * y
а затем сделать :t
я получу f :: Num b => Identity b -> Identity b
.Из этого следует, что x является Identity (Num b)
.Я могу вызвать функцию с 6
и получаю результат 12
.
Однако, если я попробую то же самое с Maybe
, вот так:
let g = \x -> Just 2 >>= \y -> x * y
<interactive>:2096:5: error:
• Non type-variable argument in the constraint: Num (Maybe b)
(Use FlexibleContexts to permit this)
• When checking the inferred type
g :: forall b. Num (Maybe b) => Maybe b -> Maybe b
Поэтому мне нужно явно вернуть Maybe
или использовать return
.Вот и я так: let g = \x -> Just 2 >>= \y -> return $ x * y
.
Все отлично работает.Однако потом мне стало интересно, что происходит с монадой Identity
.
Сначала я попытался добавить явный тип возврата следующим образом:
let f = \x -> Identity 2 >>= \y -> Identity $ x * y
, а затемсделал :t
снова, и я получил f :: Num b => b -> Identity b
.Это то, чего я ожидал в первый раз.
Что заставило меня задуматься о том, как он мог обрабатывать x + y
без Identity $
, если он выводил x
и y
вбыть завернутым в Identity
.Поэтому я попробовал следующее:
Identity 5
+ Identity 6
с результатом 11
Identity 5
+ 6
с результатом 11
снова
Тем не менее, я пытаюсь сделать то же самое с Maybe
, вот так
Just 5
+ Just 6
Just 5
+ 6
Я получаюследующая ошибка:
<interactive>:2116:1: error:
• Non type-variable argument in the constraint: Num (Maybe a)
(Use FlexibleContexts to permit this)
• When checking the inferred type
it :: forall a. (Num (Maybe a), Num a) => Maybe a
Я пытался FlexibleContexts
, но я только что получил следующую ошибку:
<interactive>:2134:1: error:
• No instance for (Num (Maybe a0)) arising from a use of ‘it’
• In the first argument of ‘print’, namely ‘it’
In a stmt of an interactive GHCi command: print it
Мне было интересно, если кто-то может пролить немного света на почемуповедение монады Identity
отличается от Maybe
?
Также возможно ли использовать FlexibleContexts
для получения того же поведения с монадой Maybe
?Я пока не смог заставить его работать.
Большое спасибо за продвинутый уровень.