我正在阅读关于Haskell书中的单子变换器。
作者提到了以下内容:
What about Monad? There’s no problem composing two arbitrary datatypes that have Monad instances. We saw this already when we used Compose with Maybe and list, which both have Monad instances defined. However, the result of having done so does not give you a Monad.
The issue comes down to a lack of information. Both types Compose is working with are polymorphic, so when you try to write bind for the Monad, you’re trying to combine two polymorphic binds into a single combined bind. This, it turns out, is not possible:
{-# LANGUAGE InstanceSigs #-} -- impossible. instance (Monad f, Monad g) => Monad (Compose f g) where return = pure (>>=) :: Compose f g a -> (a -> Compose f g b) -> Compose f g b (>>=) = ???
These are the types we’re trying to combine, because and are necessarily both monads with their own Monad instances:
Monad f => f a -> (a -> f b) -> f b Monad g => g a -> (a -> g b) -> g b
From those, we are trying to write this bind:
(Monad f, Monad g) => f (g a) -> (a -> f (g b)) -> f (g b)
Or formulated differently:
(Monad f, Monad g) => f (g (f (g a))) -> f (g a)
And this is not possible. There’s not a good way to join that final and . It’s a great exercise to try to make it work, because the barriers you’ll run into are instructive in their own right. You can also read Composing monads1 by Mark P. Jones and Luc Duponcheel to see why it’s not possible.
我无法理解,他的意思是什么?Monad transformer 是什么,它有什么用处?
IsntMonad
,为什么它不是一个 monad? 我们无法编写instance Monad IsntMonad where (IsntMonad a) >>= k = ???
吗? - softshipperIO
中提取值,然后将其应用于Kleislik :: a -> IsntMonad b
的箭头。 - freestyle>=>
运算符的函数组合一样,是单子组合。 - softshipper(>>=)
的签名 -Monad m => m a -> (a -> m b) -> m b
。第二个参数有时被称为 Kleisli 箭头(它来自 Kleisli 类别,与任何单子自然相关联,其中组合是(>=>)
)。这就是为什么第二个参数的变量被称为k
(Kleisli 的第一个字母)的原因。 - freestyleStateT s Maybe
失败的情况下,我们会丢失状态,但在MaybeT (State s)
中,我们会保存发生错误的状态。” 你能给我举个例子吗? - softshipperflip execStateT 0 (modify (+1) >> empty >> modify (+1) :: StateT Int Maybe ()) => Nothing; flip execState 0 $ runMaybeT (modify (+1) >> empty >> modify (+1) :: MaybeT (State Int) ()) => 1
- freestyle