Dea*_*nes 9 monads haskell applicative maybe
我试图去做我们必须在Haskell,这是去是再明显Just [1]
和Just [2]
到Just [1, 2]
.但是我在网上找不到任何东西,因为我一直在寻找相关但无益的页面.那么,你是如何实现这一目标的?
ehi*_*ird 16
你可以使用liftA2 (++)
:
liftA2 (++) :: Maybe [a] -> Maybe [a] -> Maybe [a]
Run Code Online (Sandbox Code Playgroud)
liftA2
只是将二进制函数提升为一个Applicative
.Applicative
s被设计用于在上下文中提升任意参数的函数,因此它们是完美的.在这种情况下,Applicative
我们正在使用的是Maybe
.要了解其工作原理,我们可以查看定义:
liftA2 :: (Applicative f) => (a -> b -> c) -> f a -> f b -> f c
liftA2 f a b = f <$> a <*> b
Run Code Online (Sandbox Code Playgroud)
(<$>)
只需将纯值上的任何函数提升为一个在内部运行的函数f
:(a -> b) -> f a -> f b
.(fmap
如果你熟悉Functor
s ,它只是一个别名.)对于Maybe
:
_ <$> Nothing = Nothing
f <$> Just x = Just (f x)
Run Code Online (Sandbox Code Playgroud)
(<*>)
有点棘手:它将一个函数应用于内部f
的值f
:f (a -> b) -> f a -> f b
.用于Maybe
:
Just f <*> Just x = Just (f x)
_ <*> _ = Nothing
Run Code Online (Sandbox Code Playgroud)
(其实f <$> x
是同样的事情pure f <*> x
,这是Just f <*> x
对Maybe
.)
所以,我们可以扩展定义liftA2 (++)
:
liftA2 (++) a b = (++) <$> a <*> b
-- expand (<$>)
liftA2 (++) (Just xs) b = Just (xs ++) <*> b
liftA2 (++) _ _ = Nothing
-- expand (<*>)
liftA2 (++) (Just xs) (Just ys) = Just (xs ++ ys)
liftA2 (++) _ _ = Nothing
Run Code Online (Sandbox Code Playgroud)
实际上,我们可以使用这些运算符将任意数量的参数的函数提升为任意参数Applicative
,只需遵循以下模式即可liftA2
.这称为applicative样式,在惯用的Haskell代码中非常常见.在这种情况下,(++) <$> a <*> b
如果a
并且b
已经是变量,通过写入直接使用它甚至可能更惯用.(另一方面,如果你部分应用它 - 比如说,将它传递给更高阶的函数 - 则更liftA2 (++)
可取.)
每一个Monad
都是一个Applicative
,所以如果你发现自己试图将一个功能"提升"到一个环境中,Applicative
那么你可能正在寻找它.
归档时间: |
|
查看次数: |
509 次 |
最近记录: |