Haskell - 让绑定选择错误的实例

时间:2015-07-06 21:41:52

标签: haskell

以下测试让我感到意外

{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
module Test where

class Type t where
    encodeToField :: t -> String

class Rec r where
    encodeToRec :: r -> String

data X a b = X a b

instance (Type t) => Rec t where
    encodeToRec = encodeToField

instance (Type t, Rec r) => Rec (X t r) where
    encodeToRec (X t r) =
        let x = encodeToField t
            y = encodeToRec r
         in x ++ y

ghc失败了

Test.hs:19:17
Could not deduce (Type r) arising from a use of `encodeToRec'
from the context (Type t, Rec r)

出于某种原因,ghc希望在Type t => Rec t使用y = encodeToRec r实例,而不是仅从实例声明的上下文中获取Rec r

如果我避免使用let绑定而是写

instance (Type t, Rec r) => Rec (X t r) where
    encodeToRec (X t r) = encodeToRec t ++ encodeToRec r

它编译。<​​/ p>

这是ghc中的错误还是因为使用了语言扩展而应该预期这种行为?

1 个答案:

答案 0 :(得分:1)

这闻起来很像known bug:当我删除通用实例时,你的代码会编译,但GHC在其存在时找不到提供的约束。我有一个相应的SO问题here。 如果这是同一个bug,它可能暂时不会修复(如果有的话)。