Декартово произведение не работает на аппликативное - PullRequest
1 голос
/ 20 апреля 2019

Я пытался понять аппликатив и как я могу использовать его как декартово произведение между K функциями и N параметрами, и я не могу понять, почему я не могу сделать следующее:

[Just (+1),Just (+2)] <*> [Just 1 ,Just 2] делает

Ошибка

* Couldn't match expected type `Maybe Integer -> b'
                  with actual type `Maybe (Integer -> Integer)'
    * Possible cause: `Just' is applied to too many arguments      In the expression: Just (+ 1)      In the first argument of `(<*>)', namely `[Just (+ 1), Just (+ 2)]'
      In the expression: [Just (+ 1), Just (+ 2)] <*> [Just 1, Just 2]

Я не понимаю, так как из определения предполагается, что функции вырваны из контекста, принимают значенияи применить все комбинации.

Я также пытался:

:t [pure (+1),pure (+2)] <*> [Just 1 ,Just 2] :: Num a => [a -> a], и я не могу понять, почему результирующий тип не является списком значений (и не a->a), так каквсе операторы ожидают только один аргумент, и я уже предоставляю его.

Может кто-нибудь пролить свет?

1 Ответ

13 голосов
/ 21 апреля 2019

Здесь задействованы два аппликативных слоя ([] и Maybe), поэтому сам (<*>) должен быть применен аппликативно:

GHCi> (<*>) <$> [Just (+1),Just (+2)] <*> [Just 1 ,Just 2]
[Just 2,Just 3,Just 3,Just 4]

Этот вариант использования зафиксирован новым типом Compose, При вложении любых двух аппликативных функторов рождается еще один аппликативный :

GHCi> import Data.Functor.Compose
GHCi> Compose [Just (+1),Just (+2)] <*> Compose [Just 1 ,Just 2]
Compose [Just 2,Just 3,Just 3,Just 4]

.

...