众所周知,应用函子在组合下是封闭的,但是monad不是.但是,我一直难以找到一个具体的反例,表明monad并不总是构成.
这个答案给出[String -> a]了一个非monad的例子.在玩了一下之后,我直觉地相信它,但是这个答案只是说"加入无法实现"而没有给出任何理由.我想要更正式的东西.当然有很多类型的函数[String -> [String -> a]] -> [String -> a]; 必须表明任何这样的功能必然不符合monad法则.
任何例子(附带证据)都可以; 我不一定特别想要证明上述例子.
每个其他monad都带有变压器版本,据我所知,变压器的概念是monad的通用扩展.跟随其他变形金刚的构建方式,IOT就像是
newtype IOT m a = IOT { runIOT :: m (IO a) }
Run Code Online (Sandbox Code Playgroud)
我可以在现场组成有用的应用程序:IOT Maybe可以执行IO操作,IOT []也可以不执行任何操作,可以构建一个稍后可以执行的列表sequence.
那么为什么Haskell中没有IO变压器呢?
(注意:我在Haskell Cafe上看过这篇文章,但对它没有多大意义.另外,ST转换器的Hackage页面在其描述中提到了一个可能相关的问题,但没有提供任何细节.)
我试图采取例如ExceptT a (StateT A M),对于一些具体类型A和monad M,并将它们包装到我的新自定义monad中.
首先,我确定了StateT A M在其他环境中经常出现,因此我决定这将是最好的单独包装在一个单子M1,然后包装ExceptT a M1成M2.
所需的属性是make M1和的M2实例MonadState和类M(假设它被调用MyMonadClass).也M2应该是一个实例MonadError.
首先我从简单类型的同义词开始:
type MyState = StateT A M
type MyBranch a = ExceptT a MyState
Run Code Online (Sandbox Code Playgroud)
然后我想我会首先勾画实例声明(没有实现实例),这就是我第一次被卡住的地方.instance MonadState A (MyState)似乎不是正确的语法.我以为我必须创建newtype MyState' a = StateT a M然后type MyState = MyState A(不要在没有必要的地方使用语言扩展).
然而,一旦我开始将同义词转换为newtype声明,我开始失去与StateT A M和 …
Haskell可以MonadState s在T1下面派生实例,但不是在T2其中是非常相似的类型.我应该以哪种方式修改代码,T2以便MonadState s可以自动派生实例?
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
import Control.Monad.Reader
import Control.Monad.State
newtype T1 r s a =
T1 { runT1 :: ReaderT r (State s) a }
deriving (Monad, MonadReader r, MonadState s)
newtype T2 r s a =
T2 { runT2 :: StateT r (State s) a }
deriving (Monad, MonadState r, MonadState s)
Run Code Online (Sandbox Code Playgroud) haskell ×4
monads ×3
newtype ×2
state-monad ×2
composition ×1
deriving ×1
io ×1
lifting ×1
proof ×1