Haskell诉斯卡拉中的类型类

Kev*_*ith 6 haskell scala typeclass

鉴于fHaskell和Scala中的以下实现:

Prelude> let f x y = x == y
Prelude> :t f
f :: Eq a => a -> a -> Bool
Run Code Online (Sandbox Code Playgroud)

斯卡拉:

scala> trait Equal[A] { def ===(x: A, y: A): Boolean }
defined trait Equal

scala> implicit val equalsInt = new Equal[Int] {
     |  def ===(x: Int, y: Int):Boolean = (x == y)
     | }
equalsInt: Equal[Int] = $anon$1@3daa422a

scala> def f[A : Equal](x: A, y: A): Boolean = 
     |   implicitly[Equal[A]].===(x, y)
f: [A](x: A, y: A)(implicit evidence$1: Equal[A])Boolean

scala> f(10, 20)
res0: Boolean = false

scala> f(55, 55)
res1: Boolean = true
Run Code Online (Sandbox Code Playgroud)

观看这个视频,Typeclasses诉世界,我的不完全理解是Scala的隐式解决方案,即它如何实现类型类,容易受到错误/不一致的implicits解析.但是,Haskell并没有对类型类使用implicits,所以在Haskell中没有这样的问题.

考虑到Scala和Haskell的类型类实现之间的差异,在Haskell f中不存在Scala中上述定义的可能问题是什么?

Yaw*_*war 5

Scala版本可能存在Haskell版本无法解决的一个问题是,在Scala中Equal[Int],当隐式解析机制试图查找实例时,您可以定义多个范围内的实例.这是什么时候你可以得到一个错误:

<console>:12: error: ambiguous implicit values:
 both value EqualInt1 of type => Equal[Int]
 and value EqualInt2 of type => Equal[Int]
 match expected type Equal[Int]
              f(1, 2)
               ^
Run Code Online (Sandbox Code Playgroud)

更新.正如Carl在评论中指出的那样,另一个问题是你可以在代码中的不同点拥有不同的实例,这样调用f可以使用这些不同的实例,结果非常不同,没有编译时或运行时错误.

  • 不仅仅是这样.你可以在不同的上下文中有不同的含义而没有错误.因此,您可以在范围内构造一些具有一种相等性的"Set"值,然后在范围内使用不同类型的相等,从而导致不一致和错误的结果.纯粹的平等对于展示这一点来说有点弱,但像Haskell的`Ord`这样的东西对于二叉搜索树来说已经足够了. (3认同)