为什么在单子中使用这种特殊的功能类型? [英] Why use such a peculiar function type in monads?
问题描述
>> =
- 具有非常特殊的类型签名: (>> =):: Monad m => m a - > (a - > m b) - > mb
为简化起见,我们用 Maybe
替代 m
:
(>> =):: Maybe a - > (a - >可能b) - >也许b
但是,请注意,定义可以写成三不同的方式:
(>> =):: Maybe a - > (也许a - >也许b) - >也许b
(>> =)::也许a - > (a - >可能b) - >也许b
(>> =)::也许a - > (a - > b) - >也许b
三者中的一个是最不对称的。然而,据我所知,如果我们想避免(LYAH称为<样板代码),那么第一个是没有意义的。但是,在接下来的两个,我宁愿最后一个。对于也许
,这看起来像:
当它定义为:
(>> =):: Maybe a - > (a - > b) - >也许b
实例Monad也许其中
Nothing>> = f = Nothing
(Just x)>> = f = return $ fx
这里, 所以也许有些东西对我来说并不明显,这导致了 a - > b
是一个普通的函数。另外,我不会立即看到任何不安全的东西,因为 Nothing
会在函数应用程序之前捕获异常,所以 a - >除非获得
函数。 Just a
,否则不会调用b
(>> =):: Maybe a - > ; (a - >可能b) - >也许b
定义优于简单得多的(>> =):Maybe a - > (a - > b) - >也许b
定义?是否存在一些与(我认为是)更简单的定义相关的固有问题?解析方案
如果您认为它更对称在下面的派生函数中(从 Control.Monad
):
(> =>):: Monad m => (a - > m b) - > (b→m c)→> (a - > mc)
(f> => g)x = fx>> = g
这个函数的意义重大的原因是它服从三个有用的方程:
pre $ - 相关性
(f> => g)> => h = f> => (g> => h)
- 左身份
返回> => f = f
- 正确的身份
f> =>返回= f
这些是类别法,如果您将它们翻译为使用(>> =)
>而不是(> =>)
,你会得到三条monad规则:
< code>>> = h = m>> = \ x - > (gx>> = h)
return x>> = f = fx
m>> = return = m
所以它的确不是(>> =)
而是(> =>)
是您正在寻找的对称运算符。然而,我们通常认为(>> =)
的原因是因为这就是 do
表示法desugars。
New to Haskell, and am trying to figure out this Monad thing. The monadic bind operator -- >>=
-- has a very peculiar type signature:
(>>=) :: Monad m => m a -> (a -> m b) -> m b
To simplify, let's substitute Maybe
for m
:
(>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
However, note that the definition could have been written in three different ways:
(>>=) :: Maybe a -> (Maybe a -> Maybe b) -> Maybe b
(>>=) :: Maybe a -> ( a -> Maybe b) -> Maybe b
(>>=) :: Maybe a -> ( a -> b) -> Maybe b
Of the three the one in the centre is the most asymmetric. However, I understand that the first one is kinda meaningless if we want to avoid (what LYAH calls boilerplate code). However, of the next two, I would prefer the last one. For Maybe
, this would look like:
When this is defined as:
(>>=) :: Maybe a -> (a -> b) -> Maybe b
instance Monad Maybe where
Nothing >>= f = Nothing
(Just x) >>= f = return $ f x
Here, a -> b
is an ordinary function. Also, I don't immediately see anything unsafe, because Nothing
catches the exception before the function application, so the a -> b
function will not be called unless a Just a
is obtained.
So maybe there is something that isn't apparent to me which has caused the (>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
definition to be preferred over the much simpler (>>=) :: Maybe a -> (a -> b) -> Maybe b
definition? Is there some inherent problem associated with the (what I think is a) simpler definition?
It's much more symmetric if you think in terms the following derived function (from Control.Monad
):
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> (a -> m c)
(f >=> g) x = f x >>= g
The reason this function is significant is that it obeys three useful equations:
-- Associativity
(f >=> g) >=> h = f >=> (g >=> h)
-- Left identity
return >=> f = f
-- Right identity
f >=> return = f
These are category laws and if you translate them to use (>>=)
instead of (>=>)
, you get the three monad laws:
(m >>= g) >>= h = m >>= \x -> (g x >>= h)
return x >>= f = f x
m >>= return = m
So it's really not (>>=)
that is the elegant operator but rather (>=>)
is the symmetric operator you are looking for. However, the reason we usually think in terms of (>>=)
is because that is what do
notation desugars to.
这篇关于为什么在单子中使用这种特殊的功能类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!