考虑到Haskell和Scala中f
的以下实现:
Prelude> let f x y = x == y
Prelude> :t f
f :: Eq a => a -> a -> Bool
Scala的:
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
观看此视频Typeclasses v. the World,我的不完全理解是Scala的隐式解决方案,即它如何实现类型类,容易受到错误/不一致解决方案的影响。但是,Haskell并没有对类型类使用含义,所以在Haskell中没有这样的问题。
考虑到Scala和Haskell的类型类实现之间的差异,在Haskell中不存在Scala中上述f
定义的可能问题是什么?
答案 0 :(得分: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)
^
更新。正如Carl在评论中指出的那样,另一个问题是你可以在代码中的不同点拥有不同的实例,这样调用f
可以使用这些不同的实例,结果非常不同,没有编译时间或运行 - 时间错误。