Haskell - применение функции, которая возвращает функтор на функтор - PullRequest
3 голосов
/ 07 марта 2020

Скажем, у меня есть две функции функции f и g, которые обе принимают регулярные значения и возвращают значение Either следующим образом:

g :: a -> Either x b
f :: b -> Either x c

Как объединить эти две функции вместе, чтобы получить что-то вроде f . g?

Лучшее решение, которое я придумала, - это создание вспомогательной функции с именем applyToRight, которая работает следующим образом

applyToRight :: (a -> Either x b) -> Either x a -> Either x b
applyToRight f x =
  case x of
    Left a -> Left a
    Right b -> f b

Так что я могу сделать

applyToRight f (g a)

В данном случае я конкретно говорю о Either, но я думаю, что эту проблему можно обобщить на все аппликативные функторы. Какой самый элегантный способ справиться с этим?

Ответы [ 2 ]

7 голосов
/ 07 марта 2020

Не относится. Вы заново открыли Monadi c bind:

(>>=) :: Monad m => m a -> (a -> m b) -> m b

Either x - это монада:

> Left "a" >>= (\x -> Right (1+x))
Left "a"

> Right 1 >>= (\x -> Right (1+x))
Right 2

Объединение двух функций, создающих монады, как у вас, сделано с композицией Kleisli оператор, например f <=< g, или эквивалентно в другом направлении g >=> f с оператором прямого сложения,

(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c

, с этими типами легче следовать:

      f ::               b -> Either x c
g       :: a -> Either x b
-----------------------------------------
g >=> f :: a ->               Either x c

Фактически, один из способов суммировать монады состоит в том, чтобы сказать, что они относятся к обобщенной композиции функции .

>=> определяется просто как

(g >=> f) x  =  g x >>= f 

(f <=< g) x  =  g x >>= f  =  f =<< g x

См. Также:

3 голосов
/ 07 марта 2020

Функтор и Applicative слишком слабы: Monad содержит искомую функцию.

applyToRight = flip (>>=)
...