【发布时间】:2015-01-22 00:25:13
【问题描述】:
我正在尝试使用 lens 来修改 StateT Monad Transformer 中的状态。据我了解,这段代码应该可以编译:
{-# LANGUAGE TemplateHaskell #-}
import Control.Lens (makeLenses, (+=))
import Control.Monad.State (State)
data Game = Game {
_player :: String,
_points :: Int
} deriving (Show)
makeLenses ''Game
play :: State Game ()
play = do
points += 10
return ()
main :: IO ()
main = undefined
但 ghc 告诉我:
No instance for (mtl-2.1.3.1:Control.Monad.State.Class.MonadState
Game
(Control.Monad.Trans.State.Lazy.StateT
Game Data.Functor.Identity.Identity))
arising from a use of ‘+=’
...
我看到mtl 可能是问题所在,所以我输入ghc-pkg hide mtl,然后再次编译:没有错误,它编译!
我已经安装了 transformers 库,所以它正在使用它,这很有帮助。
然后我通过更改这两行将State 更改为StateT:import Control.Monad.State (State) -> import Control.Monad.Trans.State (StateT) 和play :: State Game () -> play :: StateT Game IO (),编译器再次返回类似的错误。怎么回事?
【问题讨论】:
-
您是否安装了多个版本的 mtl?如果是这样,请确保 ghc 没有在一个程序中使用两个不同版本的 mtl。
-
与其直接调用 ghc,不如考虑快速创建一个 cabal 包,然后用 cabal 构建它。如果你有依赖冲突,阴谋集团会对你大喊大叫。希望这将使问题更加明显。
-
我尝试构建您的程序并且它顺利进行,所以我相当确定这是由于您的程序使用的 mtl 版本与 lens 使用的不同。 GHC 在错误消息中报告版本号这一事实是一个巨大的危险信号。 (另外,你的程序直接使用 mtl,所以没有 mtl 就无法编译你的程序。)
-
是的,如果类型错误提到了版本号,几乎可以肯定是包冲突。
-
好的,我确实有一个损坏的包 db,使用
ghc-pkg check确认。我可以解决问题,现在一切正常。谢谢大家!
标签: haskell monad-transformers haskell-lens