【发布时间】:2018-04-11 18:31:23
【问题描述】:
我在一个 Haskell 应用程序中有两个或多个独立状态要跟踪。
我正在使用
声明两个新类型类type MonadTuple m = MonadState (Int, Int) m
type MonadBool m = MonadState Bool m
monad 转换器栈被声明为
type Stack = StateT (Int, Int) (StateT Bool IO) ()
我打算这样使用堆栈
ret :: Stack
ret = apply
apply :: (MonadTuple m, MonadBool m) => m ()
apply = undefined
编译器很不高兴,因为在尝试检查Stack 是否符合MonadBool 时,它无法将Bool 与(Int, Int) 匹配。
我知道Combining multiple states in StateT 中给出的解决方案。除了箭头或带镜头的全局状态之外,还有其他更简单的解决方案吗?
附录: 完整的代码块是
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
import Control.Monad.State.Class
import Control.Monad.State.Lazy
type MonadTuple m = MonadState (Int, Int) m
type MonadBool m = MonadState Bool m
type Stack = StateT (Int, Int) (StateT Bool IO) ()
ret :: Stack
ret = apply
apply :: (MonadTuple m, MonadBool m) => m ()
apply = undefined
【问题讨论】:
-
您将其命名为
Stack有什么原因吗? -
我将其命名为
Stack以建议使用 monad 转换器stack。 -
在这种情况下,它不应该将硬编码的
()作为值类型。 -
我同意。如果以多态方式使用转换器,则不硬编码会更清晰。
标签: haskell monad-transformers state-monad