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.Applicatives被设计用于在上下文中提升任意参数的函数,因此它们是完美的.在这种情况下,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如果你熟悉Functors ,它只是一个别名.)对于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那么你可能正在寻找它.