dem*_*emi 3 monads haskell instance typeclass
让我从我想解决的任务开始,可能是我走错了路.我将Snap框架用于玩具项目,主要是它在Snapmonad 下的功能.我需要在它上面添加我的状态.我用monad变压器:
type SnapApp a = StateT AppState Snap a
Run Code Online (Sandbox Code Playgroud)
例如,这在模块中定义Base.由于我在其他模块中需要它,我必须导出它:
module Base
( ..
, SnapApp
) where
Run Code Online (Sandbox Code Playgroud)
这很好,但我希望该模块不会导出SnapApp状态monad,因为我有一些复杂的处理来为状态设置一些属性.例如,会话.我有当它变以写入文件,因此它不应当只是get比put修改的会话,特殊功能应该被调用.所以,我隐藏了使用newtype而不是数据导出construstor:
newtype SnapApp a = SnapApp (StateT AppState Snap a)
Run Code Online (Sandbox Code Playgroud)
我创建了我的类的实例,其中包含用于修改会话等的函数.但问题出现了:我丢失了Monad类和其他类的实例SnapApp.我坚持执行>>=:
instance Monad SnapApp where
return = SnapApp . return
mx >>= fm = -- HOW?
Run Code Online (Sandbox Code Playgroud)
谢谢!
sdc*_*vvc 16
让类型指导你.你需要
(>>=) :: SnapApp a -> (a -> SnapApp b) -> SnapApp b
Run Code Online (Sandbox Code Playgroud)
你有
(>>=) :: StateT AppState Snap a -> (a -> StateT AppState Snap b) -> StateT AppState Snap b
Run Code Online (Sandbox Code Playgroud)
你需要转换:
SnapApp a到StateT AppState Snap aa -> SnapApp b到a -> StateT AppState Snap bStateT AppState Snap b到SnapApp b1)使用模式匹配; 限定:
fromSnapApp (SnapApp x) = x
Run Code Online (Sandbox Code Playgroud)
2)撰写功能a -> SnapApp b和SnapApp b -> StateT AppState b
3)使用 SnapApp
最后结果:
x >>= f = SnapApp (fromSnapApp x >>= (fromSnapApp . f))
Run Code Online (Sandbox Code Playgroud)
要么:
SnapApp x >>= f = SnapApp (x >>= (fromSnapApp . f))
Run Code Online (Sandbox Code Playgroud)
你不必写这个; 如果启用GeneralizedNewtypeDeriving扩展,GHC可以派生实例:
newtype SnapApp a = SnapApp (StateT AppState Snap a) deriving (Monad)
Run Code Online (Sandbox Code Playgroud)