定义 Monad 运算符
Defining Monad Operators
在 Haskell 的 Monad 中,我可以轻松地将运算符 (>=>)
定义为:
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c
f >=> g = \x -> f x >>= g
我也知道 (>>=)
可以用 (>=>)
表示:让我们称 (>>=)
为 (..)
:
(..) :: Monad m => m a -> (a -> m b) -> m b
m .. k = m >=> \_ -> k
但是有些地方不对...有人能指出什么吗?
使用常量函数(即 \_ -> -- etc.
)从不是函数的参数中创建函数以便将其传递给 (>=>)
的想法是合理的.只有两个问题。首先,你这样做是为了错误的论点,因为不是函数的论点是 m
:
GHCi> :t \m k -> (\_ -> m) >=> k
\m k -> (\_ -> m) >=> k :: Monad m => m b -> (b -> m c) -> a -> m c
其次,(>=>)
为您提供了一个函数(在上面的演示中属于 a -> m c
类型)。您必须将它应用于某些东西才能获得与 (>>=)
之一匹配的结果类型。由于该参数无关紧要(您最终将其提供给常量函数),您可以只使用 ()
:
GHCi> :t \m k -> ((\_ -> m) >=> k) ()
\m k -> ((\_ -> m) >=> k) () :: Monad m => m b -> (b -> m c) -> m c
就是这样。我发现使用 const
函数比写 \_ ->
稍微漂亮一点,所以我会把它写成:
(>>..) :: Monad m => m a -> (a -> m b) -> m b
m >>.. k = (const m >=> k) ()
解决方法如下:
(..) :: Monad m => m a -> (a -> m b) -> m b
m .. k =
(const m >=> k) undefined
我们使用 const
将 m a
类型的操作提升到 whatever -> m a
。这个提升版本不在乎我们传递给它的东西,所以它也可能是 undefined
.
在 Haskell 的 Monad 中,我可以轻松地将运算符 (>=>)
定义为:
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c
f >=> g = \x -> f x >>= g
我也知道 (>>=)
可以用 (>=>)
表示:让我们称 (>>=)
为 (..)
:
(..) :: Monad m => m a -> (a -> m b) -> m b
m .. k = m >=> \_ -> k
但是有些地方不对...有人能指出什么吗?
使用常量函数(即 \_ -> -- etc.
)从不是函数的参数中创建函数以便将其传递给 (>=>)
的想法是合理的.只有两个问题。首先,你这样做是为了错误的论点,因为不是函数的论点是 m
:
GHCi> :t \m k -> (\_ -> m) >=> k
\m k -> (\_ -> m) >=> k :: Monad m => m b -> (b -> m c) -> a -> m c
其次,(>=>)
为您提供了一个函数(在上面的演示中属于 a -> m c
类型)。您必须将它应用于某些东西才能获得与 (>>=)
之一匹配的结果类型。由于该参数无关紧要(您最终将其提供给常量函数),您可以只使用 ()
:
GHCi> :t \m k -> ((\_ -> m) >=> k) ()
\m k -> ((\_ -> m) >=> k) () :: Monad m => m b -> (b -> m c) -> m c
就是这样。我发现使用 const
函数比写 \_ ->
稍微漂亮一点,所以我会把它写成:
(>>..) :: Monad m => m a -> (a -> m b) -> m b
m >>.. k = (const m >=> k) ()
解决方法如下:
(..) :: Monad m => m a -> (a -> m b) -> m b
m .. k =
(const m >=> k) undefined
我们使用 const
将 m a
类型的操作提升到 whatever -> m a
。这个提升版本不在乎我们传递给它的东西,所以它也可能是 undefined
.