[英]Composition of Applicative functions
我可以編寫純函數:
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
我想我應該能夠將上一個示例中的f
和g
看作是應用程序,並且也可以將它們組合起來,只是不確定如何:
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
這可行嗎?
獎勵積分, zx = fx >>= g
可以寫為無積分函數嗎? 像z = f >>= g
?
{-# LANGUAGE TypeOperators #-}
任何兩個應用函子的(類型級別)組成,
newtype (f :. g) a = Compose { getCompose :: f (g a)) }
是實用的函子 。
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)
您的示例是Maybe
應用程序與“ function”或“ reader”應用程序(->) r
。
type ReaderWithMaybe r = ((->) r) :. Maybe
x, y :: ReaderWithMaybe Int Int
x = Compose $ \x -> Just (x + 1)
y = Compose $ \x -> Just (x + 2)
由於ReaderWithMaybe r
是一個Applicative
您可以執行所有常用的Applicative
。 在這里,我將兩個值與+
一起粉碎。
ghci> let z = (+) <$> x <*> y
ghci> getCompose z 3
Just 9 -- (3 + 1) + (3 + 2) == 9
請注意, x
和y
都獲得相同的輸入 3
。 這就是(->) r
的Applicative
實例的行為。 如果你想利用的結果 fx = Just (x + 1)
並將其送入gx = Just (x + 2)
得到的東西等同於hx = Just (x + 3)
那么,這就是Monad
是對於。
獎勵積分,
zx = fx >>= g
可以寫為無積分函數嗎? 像z = f >>= g
?
您可以輕松地手動定義Kleisli的成分。
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c
f >=> g = \x -> f x >>= g
碰巧標准庫中已經存在>=>
及其姐妹<=<
。 他們被稱為“魚”操作員,他們生活在Control.Monad
。
應用功能不是
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 (.) fg
或(.) <$> f <*> g
。
也許您會對Kleisli單子的組成感興趣:
(<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.