使用更多类型变量派生 newtype
Deriving in newtype with more type variables
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 有效而 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)
我认为 MyNewType4
被认为是不安全的,因此不允许派生,因为它违反了第二个帕特森条件:
MyNewtype4 f v
有 3 个,f (Maybe v)
也有 3 个。 MyNewtype2 f maybe v
有 4,因此 instance (Eq (f (maybe v))) => MyNewtype2 f maybe v
服从条件(遵循开头引用的规则的任何情况也是如此)。
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 有效而 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)
我认为 MyNewType4
被认为是不安全的,因此不允许派生,因为它违反了第二个帕特森条件:
MyNewtype4 f v
有 3 个,f (Maybe v)
也有 3 个。 MyNewtype2 f maybe v
有 4,因此 instance (Eq (f (maybe v))) => MyNewtype2 f maybe v
服从条件(遵循开头引用的规则的任何情况也是如此)。