应用功能的组成

zor*_*119 1 haskell functional-programming

我可以撰写纯函数:

let f x = x + 1
let g x = x + 2
let z = f . g
z 1 == 4
Run Code Online (Sandbox Code Playgroud)

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

let f x = Just (x + 1)
let g x = Just (x + 2)
let z x = f x >>= g
z 1 == Just 4
Run Code Online (Sandbox Code Playgroud)

我想我应该能够对待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
Run Code Online (Sandbox Code Playgroud)

这可行吗?

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

Ben*_*son 6

{-# LANGUAGE TypeOperators #-}
Run Code Online (Sandbox Code Playgroud)

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

newtype (f :. g) a = Compose { getCompose :: f (g a)) }
Run Code Online (Sandbox Code Playgroud)

是一个应用函子.

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)
Run Code Online (Sandbox Code Playgroud)

你的例子是组合物Maybe应用性"功能"或"阅读器"应用性(->) r.

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

x, y :: ReaderWithMaybe Int Int
x = Compose $ \x -> Just (x + 1)
y = Compose $ \x -> Just (x + 2)
Run Code Online (Sandbox Code Playgroud)

既然ReaderWithMaybe rApplicative你可以做所有常见的Applicative事情.在这里,我正在粉碎我的两个价值观+.

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

请注意,xy都得到了相同的输入 3.这是行为(->) rApplicative实例.如果你想利用的结果f x = Just (x + 1),并送入g x = Just (x + 2)(得到的东西相当于h x = Just (x + 3)),那么,这是什么Monad是.


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

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

(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c
f >=> g = \x -> f x >>= g
Run Code Online (Sandbox Code Playgroud)

它发生>=>在标准库中已经存在,还有它的姐妹<=<.他们被称为"鱼"经营者,他们住在这里Control.Monad.