其中一个依赖项的覆盖条件失败

时间:2014-03-28 21:21:09

标签: haskell

我试图编写使用monad变换器的函数,但对于我的monadic类型的确切结构是不可知的。但是,我并不完全理解我在做什么 - 尝试遵循我对#haskell的建议。我的想法是想写一个像

这样的函数
doSomething :: (MonadRandom m, MonadError MyError m ) => Arg -> m Result

(其中m是添加随机生成器状态和错误处理的monad变换器的堆栈)

我开始写一些州:

{-# LANGUAGE GeneralizedNewtypeDeriving, MultiParamTypeClasses, FlexibleInstances #-}

import System.Random
import Control.Monad.Error
import Control.Monad.State

{-
-- I want to make a class of monads which contain random generator state.
class Monad m => RandMonad m where
  putGen :: StdGen -> m ()
  getGen :: m StdGen
-}

-- the following creates a monadic type BT
data BTState = BTState
 { bGoalN :: Int
 , bRandState :: StdGen }
newtype BT m a = BT { runBT :: StateT BTState m a }

-- what the following does is say that if e and m can be used the 
-- way a monad error can be used, then so can e and (BT m)
instance MonadError e m => MonadError e (BT m) where
   throwError x = BT (throwError x)
   -- edit: I added the following definition but I'm still getting the same error
   -- In fact I tried every conceivable definition of catchError and still get the
   -- same error about the coverage condition
   catchError (BT x) y = BT (catchError y)

当我运行这个时,我得到了" MonadError e(BT m)'非法实例声明。 (其中一个依赖项的覆盖条件失败)"

我是一名哈斯克尔新手,所以我不知道这意味着什么。

1 个答案:

答案 0 :(得分:1)

覆盖条件与实现实例的方式无关。在MonadError

的定义中
class (Monad m) => MonadError e m | m -> e where

函数依赖性表示对于给定的实例m,我们必须能够唯一地确定e

问题在于像你这样的定义

instance MonadError e m => MonadError e (BT m) where

GHC无法确定BT m我们可以确定mm(使用实例MonadError e m)我们可以确定{{1} }}。因此,为了定义您的实例,您需要启用e。另见How to get around the Coverage Condition for Functional Dependencies without using -XUndecidableInstances。请注意,所有UndecidableInstances个实例都是这样定义的,请参阅the source

在您的情况下,我建议使用现有的MonadRandom及其相应的monad变换器RandT。您必须自己为MonadError定义MonadError个实例。