使用更多类型变量导出newtype

时间:2016-09-08 11:12:35

标签: haskell deriving newtype

newtype MyNewtype1 f v = MyNewtype1 { getVal1 :: f v } deriving Eq -- OK
newtype MyNewtype2 f maybe v = MyNewtype2 { getVal2 :: f (maybe v) } deriving Eq --OK
newtype MyNewtype3 f v = MyNewtype3 { getVal3 :: f (Maybe v) } --  OK
newtype MyNewtype4 f v = MyNewtype4 { getVal4 :: f (Maybe v) } deriving Eq --NOT OK

我有这些新类型。前三个按预期工作,但第四个给出:

    • No instance for (Eq (f (Maybe v)))
        arising from the 'deriving' clause of a data type declaration
      Possible fix:
        use a standalone 'deriving instance' declaration,
          so you can specify the instance context yourself
    • When deriving the instance for (Eq (MyNewtype4 f v))

我无法理解问题出在哪里。在我看来,第二个新类型严格更普遍,因此必须遇到同样的问题。因此,如果MyNewtype2可以导出Eq,为什么MyNewtype2不能?这可能让我最困惑。有人可以向我解释一下吗?另外,如果我想要这样的新类型,首选的解决方案是什么?

2 个答案:

答案 0 :(得分:4)

我不知道为什么2个有效但4个没有。可能与灵活的上下文有关(我不太清楚,不能解释)。

要回答第二个问题......首选的解决方案,如果你想要一个类似的新类型,就像GHC建议的那样:使用一个独立的派生实例。

{-# LANGUAGE StandaloneDeriving, FlexibleContexts, UndecidableInstances #-}

newtype MyNewtype4 f v = MyNewtype4 { getVal4 :: f (Maybe v) }
deriving instance (Eq (f (Maybe v))) => Eq (MyNewtype4 f v)

答案 1 :(得分:3)