Haskell 带有类型构造函数的类型类定义实例
Haskell instance of typeclass definition with type constructor
data CouldBe a = Is a | Lost deriving (Show, Ord)
instance Eq (CouldBe m) where
Is x == Is y = x == y
Lost == Lost = True
_ == _ = False
报错:No instance for (Eq m) arising from a use of ‘==’
所以:
instance (Eq m) => Eq (CouldBe m) where
Is x == Is y = x == y
Lost == Lost = True
_ == _ = False
工作正常(至少我开始理解错误),但为什么我需要那个约束?
我正在努力学习,所以 'why' 对我来说非常重要。
您最初的定义是 CouldBe m
是 any 类型 m
的 Eq
实例,即使没有一个 Eq
实例。但如果这是真的,你必须找到一些不使用 x == y
来定义 Is x == Is y
的方法(因为你不需要 m
来拥有一个 Eq
实例,x == y
不一定定义。)
举个具体的例子,它会阻止你写类似
的东西
Is (+3) == Is (* 5) -- (+3) == (*5) is undefined
添加约束确保您可以比较两个 CouldBe
值,前提是包装类型也可以进行比较。
A "valid",但很简单,没有添加约束的实例:
instance Eq (CouldBe m) where
Is x == Is y = True
Lost == Lost = True
_ == _ = False
两个 CouldBe m
值只要共享相同的数据构造函数就相等,无论包装值如何。根本没有尝试使用 x
或 y
,因此它们的类型可以不受约束。
"Valid" 在引号中,因为此定义可能违反了 http://hackage.haskell.org/package/base-4.12.0.0/docs/Data-Eq.html 中定义的替代法则。假设您有一个函数可以拆分 CouldBe
值:
couldbe :: b -> (a -> b) -> CouldBe a -> b
couldBe x _ Lost = x
couldBe _ f (Is x) = f x
发生违规是因为 Is 3 == Is 5
为真,但让 f = couldbe 0 id
。然后 f (Is 3) == f (Is 5)
的计算结果为 3 == 5
,这是错误的。
是否实际上违规取决于是否存在像couldbe
这样的函数可以看到"inside"一个CouldBe
值.
data CouldBe a = Is a | Lost deriving (Show, Ord)
instance Eq (CouldBe m) where
Is x == Is y = x == y
Lost == Lost = True
_ == _ = False
报错:No instance for (Eq m) arising from a use of ‘==’
所以:
instance (Eq m) => Eq (CouldBe m) where
Is x == Is y = x == y
Lost == Lost = True
_ == _ = False
工作正常(至少我开始理解错误),但为什么我需要那个约束? 我正在努力学习,所以 'why' 对我来说非常重要。
您最初的定义是 CouldBe m
是 any 类型 m
的 Eq
实例,即使没有一个 Eq
实例。但如果这是真的,你必须找到一些不使用 x == y
来定义 Is x == Is y
的方法(因为你不需要 m
来拥有一个 Eq
实例,x == y
不一定定义。)
举个具体的例子,它会阻止你写类似
的东西Is (+3) == Is (* 5) -- (+3) == (*5) is undefined
添加约束确保您可以比较两个 CouldBe
值,前提是包装类型也可以进行比较。
A "valid",但很简单,没有添加约束的实例:
instance Eq (CouldBe m) where
Is x == Is y = True
Lost == Lost = True
_ == _ = False
两个 CouldBe m
值只要共享相同的数据构造函数就相等,无论包装值如何。根本没有尝试使用 x
或 y
,因此它们的类型可以不受约束。
"Valid" 在引号中,因为此定义可能违反了 http://hackage.haskell.org/package/base-4.12.0.0/docs/Data-Eq.html 中定义的替代法则。假设您有一个函数可以拆分 CouldBe
值:
couldbe :: b -> (a -> b) -> CouldBe a -> b
couldBe x _ Lost = x
couldBe _ f (Is x) = f x
发生违规是因为 Is 3 == Is 5
为真,但让 f = couldbe 0 id
。然后 f (Is 3) == f (Is 5)
的计算结果为 3 == 5
,这是错误的。
是否实际上违规取决于是否存在像couldbe
这样的函数可以看到"inside"一个CouldBe
值.