应用功能的组成

时间:2016-04-25 11:48:10

标签: haskell functional-programming

我可以编写纯函数:

let f x = x + 1
let g x = x + 2
let z = f . g
z 1 == 4

我似乎也能够组成monadic函数:

let f x = Just (x + 1)
let g x = Just (x + 2)
let z x = f x >>= g
z 1 == Just 4

我认为我应该能够将上一个示例中的fg视为应用并将其组合起来,但不确定如何:

let f x = Just (x + 1)
let g x = Just (x + 2)
let z x = f <*> g -- this doesn't work
z 1 == Just 4

这可行吗?

奖励积分,z x = f x >>= g可以写成无点功能吗?像z = f >>= g

这样的东西

3 个答案:

答案 0 :(得分:6)

{-# LANGUAGE TypeOperators #-}

任何两个应用函子的(类型级)组合,

newtype (f :. g) a = Compose { getCompose :: f (g a)) }

is an applicative functor

instance (Functor f, Functor g) => Functor (f :. g) where
    fmap f = Compose . fmap (fmap f) . getCompose

instance (Applicative f, Applicative g) => Applicative (f :. g) where
    pure = Compose . pure . pure
    Compose fgf <*> Compose fgx = Compose ((<*>) <$> fgf <*> fgx)

您的示例是the Maybe applicativethe "function" or "reader" applicative (->) r的组合。

type ReaderWithMaybe r = ((->) r) :. Maybe

x, y :: ReaderWithMaybe Int Int
x = Compose $ \x -> Just (x + 1)
y = Compose $ \x -> Just (x + 2)

由于ReaderWithMaybe rApplicative,您可以执行所有常规Applicative内容。在这里,我与+一起粉碎了我的两个价值观。

ghci> let z = (+) <$> x <*> y
ghci> getCompose z 3
Just 9  -- (3 + 1) + (3 + 2) == 9

请注意,xy都会获得相同的输入 3。这就是(->) r的{​​{1}}实例的行为。如果你想取Applicative结果并将其输入f x = Just (x + 1)(以获得与g x = Just (x + 2)相当的东西),那就是{{1}是为了。

  

奖励积分,h x = Just (x + 3)可以写成无点功能吗?像Monad

这样的东西

您可以手动轻松定义Kleisli成分。

z x = f x >>= g

标准库中已存在z = f >>= g及其姐妹(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c f >=> g = \x -> f x >>= g 。他们被称为“鱼”操作员,他们住在Control.Monad

答案 1 :(得分:2)

应用功能不是

let f x = Just $ x + 1
let g x = Just $ x + 2

,他们是

let f = Just $ \x -> x + 1
let g = Just $ \x -> x + 2

。然后,合成就像liftA2 (.) f g(.) <$> f <*> g一样。

答案 2 :(得分:0)

也许你会对Kleisli monad的成分感兴趣:

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