【发布时间】:2023-03-22 10:25:01
【问题描述】:
Set 不是函子的原因是here。似乎可以归结为a == b && f a /= f b 是可能的。那么,为什么 Haskell 没有标准的 Eq 替代方案,比如
class Eq a => StrongEq a where
(===) :: a -> a -> Bool
(/==) :: a -> a -> Bool
x /== y = not (x === y)
x === y = not (x /== y)
哪些情况应该遵守法律
∀a,b,f. not (a === b) || (f a === f b)
∀a. a === a
∀a,b. (a === b) == (b === a)
也许还有其他人?那么我们可以:
instance StrongEq a => Functor (Set a) where
-- ...
还是我错过了什么?
编辑:我的问题不是“为什么会有没有Eq 实例的类型?”,就像你们中的一些人似乎已经回答的那样。恰恰相反:“为什么Eq 的实例在扩展上不相等?为什么Eq 实例太多?”,结合“如果a == b 确实暗示外延相等,为什么Set 不是Functor 的实例?”。
另外,我的实例声明是垃圾(感谢@n.m.)。我应该说:
newtype StrongSet a = StrongSet (Set a)
instance Functor StrongSet where
fmap :: (StrongEq a, StrongEq b) => (a -> b) -> StrongSet a -> StrongSet b
fmap (StrongSet s) = StrongSet (map s)
【问题讨论】:
-
我认为迈克尔的例子是无效的。
==is 应该见证“通过所有可观察的方式等效”(这并不一定要求a == b必须仅适用于 相同的实现;但是您可以做的任何事情“正式“与a和b一起做应该再次产生相同的结果。所以unAlwaysEq不应该首先暴露)。如果您无法确保某些类型的这一点,则不应为其提供Eq实例。 -
如果你定义了一个没有意义的实例,你应该期望你编写的代码有奇怪的行为。
Set不是函子,因为Set.map的输出类型需要Ord约束。实例instance Functor (Set a) where ...甚至无效。 -
在 Scala 中存在
fmap对应于Set,它曾多次咬过我(和同事)。 -
对于任何有趣的类型,你的第一个属性如何才能成立?
Int肯定不可能是StrongEq的实例,因为存在f :: Int -> Int其中a === b && not (f a === f b)。 -
@JamesWood 问题总是映射一个
Set,这样两个不同的元素被映射为相等;但目的是保留重复项。例如。你有一组对象,想要总结它们的成本。如果您将对象映射到它们的成本然后求和,如果您得到一组介于两者之间的成本,那么您只计算具有相同成本的对象一次。
标签: haskell functional-programming functor typeclass