【问题标题】:Lens and State, library inconsistencies镜头和状态,图书馆不一致
【发布时间】: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 更改为StateTimport 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


【解决方案1】:

感谢 Rufflewind 的提示,我通过修复包不一致解决了这个问题(请参阅上面对我的问题的评论)。

我首先使用ghc-pkg check 检查我现有的包配置,然后使用ghc-pkg unregister --force 删除所有损坏的包。我反复重复它,直到找不到更多损坏的包。然后我重新安装了镜头,现在它可以工作了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-15
    • 2014-11-12
    • 2013-12-16
    • 2016-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多