为什么Haskell没有比Eq更强大的替代方案? [英] Why doesn't Haskell have a stronger alternative to Eq?

查看:358
本文介绍了为什么Haskell没有比Eq更强大的替代方案?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么 Set 不是一个函子,因为 here 。这似乎归结为以下事实: a == b&& f a / = f b 是可能的。那么,为什么Haskell没有像Eq那样的标准替代方案,就像

  class Eq a => StrongEq a其中
(===):: a - > a - > Bool
(/ ==):: a - > a - > Bool
x / == y = not(x === y)
x === y = not(x / == y)

哪些实例应该服从法律

 ∀a, b,F。不(a === b)|| (f a === f b)
∀a。 a === a
∀a,b。 (a === b)==(b === a)

或者其他一些?然后我们可以有:

 实例StrongEq a => Functor(Set a)其中
- ...

或者我错过了什么?






编辑:我的问题不是为什么没有 Eq instance?,就像你们中的一些人似乎已经回答了一样。情况恰恰相反:为什么 Eq 不是延伸平等的实例?为什么存在太多 Eq 个实例?,加上If a == b 确实意味着扩展的相等性, Set 不是 Functor ?的实例。



另外,我的实例声明是垃圾(谢谢@ nm)。我应该说:

  newtype StrongSet a = StrongSet(Set a)
实例Functor StrongSet其中
fmap ::(StrongEq a,StrongEq b)=> (a - > b) - > StrongSet a - > StrongSet b
fmap(StrongSet s)= StrongSet(map s)


解决方案

你的第二个 Functor 实例也没有任何意义。 Haskell中 Set 不能是 Functor 的最大原因是 fmap 不能有约束。在> StrongEq 中发明不同的平等概念并不会改变你不能在 fmap 中写入这些约束的事实。你的Set实例。



fmap 一般情况下不应该有你需要的限制。例如,具有函数的函数是非常有意义的(例如,没有它使用Applicative在函子内部应用函数的整个概念失效),函数不能是Eq或您的StrongEq的成员。



fmap 不能仅在某些实例上有额外的约束,因为这样的代码:

  fmapBoth ::(Functor f,Functor g)=> (a→b,c→d)→> (f a,g c) - > (fb,gd)
fmapBoth(h,j)(x,y)=(fmap hx,fmap jy)

这个代码声称不管函子是什么 f g ,并且不管函数 h j 。它无法检查其中一个函数是否是对 fmap 有额外约束的特殊函数,也没有办法检查它所应用的函数是否会违反这些函数约束。

说到Set是Haskell中的Functor,就是说有一个(合法的)操作 fmap ::(a - > b) - >设置 - >使用该确切类型设置b 。那就是恰恰 Functor 的意思。 fmap ::(等式 - >等式b)=> (a - > b) - >设置 - >设置b 不是这种操作的例子。



据我所知,使用 ConstraintKinds GHC扩展来写一个不同的 Functor类允许对函数值有所不同的值进行约束(并且您实际需要的是 Ord 约束,而不仅仅是 Eq )。 这篇博客文章谈到了如何做一个新的Monad类可以有一个Set的实例。我从来没有玩过这样的代码,所以我不知道这个技术的存在。它不会帮助您将Sets移交给需要Functors的现有代码,但是如果您愿意,您可以在自己的代码中使用它而不是Functor。


The reason why Set is not a functor is given here. It seems to boil down to the fact that a == b && f a /= f b is possible. So, why doesn't Haskell have as standard an alternative to Eq, something like

class Eq a => StrongEq a where
    (===) :: a -> a -> Bool
    (/==) :: a -> a -> Bool
    x /== y = not (x === y)
    x === y = not (x /== y)

for which instances are supposed to obey the laws

∀a,b,f. not (a === b) || (f a === f b)
∀a. a === a
∀a,b. (a === b) == (b === a)

and maybe some others? Then we could have:

instance StrongEq a => Functor (Set a) where
    -- ...

Or am I missing something?


Edit: my problem is not "Why are there types without an Eq instance?", like some of you seem to have answered. It's the opposite: "Why are there instances of Eq that aren't extensionally equal? Why are there too many Eq instances?", combined with "If a == b does imply extensional equality, why is Set not an instance of Functor?".

Also, my instance declaration is rubbish (thanks @n.m.). I should have said:

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)

解决方案

Your second Functor instance also doesn't make any sense. The biggest reason why Set can't be a Functor in Haskell is fmap can't have constraints. Inventing different notions of equality as StrongEq doesn't change the fact that you can't write those constraints on fmap in your Set instance.

fmap in general shouldn't have the constraints you need. It makes perfect sense to have functors of functions, for example (without it the whole notion of using Applicative to apply functions inside a functor breaks down), and functions can't be members of Eq or your StrongEq in general.

fmap can't have extra constraints on only some instances, because of code like this:

fmapBoth :: (Functor f, Functor g) => (a -> b, c -> d) -> (f a, g c) -> (f b, g d)
fmapBoth (h, j) (x, y) = (fmap h x, fmap j y)

This code claims to work regardless of the functors f and g, and regardless of the functions h and j. It has no way of checking whether one of the functors is a special one that has extra constraints on fmap, nor any way of checking whether one of the functions it's applying would violate those constraints.

Saying that Set is a Functor in Haskell, is saying that there is a (lawful) operation fmap :: (a -> b) -> Set a -> Set b, with that exact type. That is precisely what Functor means. fmap :: (Eq a -> Eq b) => (a -> b) -> Set a -> Set b is not an example of such an operation.

It is possible, I understand, to use the ConstraintKinds GHC extendsion to write a different Functor class that permits constraints on the values which vary by Functor (and what you actually need is an Ord constraint, not just Eq). This blog post talks about doing so to make a new Monad class which can have an instance for Set. I've never played around with code like this, so I don't know much more than that the technique exists. It wouldn't help you hand off Sets to existing code that needs Functors, but you should be able to use it instead of Functor in your own code if you wish.

这篇关于为什么Haskell没有比Eq更强大的替代方案?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆