簡體   English   中英

適用功能的組成

[英]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

我想我應該能夠將上一個示例中的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

這可行嗎?

獎勵積分, 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

請注意, xy都獲得相同的輸入 3 這就是(->) rApplicative實例的行為。 如果你想利用的結果 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM