scala - Haskell v. Scala 中的类型类

标签 scala haskell typeclass

给定 f 的以下实现在 Haskell 和 Scala 中:

Prelude> let f x y = x == y
Prelude> :t f
f :: Eq a => a -> a -> Bool

斯卡拉:
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 的 typeclass 实现之间的差异,以上 f 可能出现的问题是什么? Haskell中没有的Scala中的定义?

最佳答案

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可以使用这些不同的实例,结果非常不同,并且没有编译时或运行时错误。

关于scala - Haskell v. Scala 中的类型类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31259389/

相关文章:

haskell - 避免在 Hughes 的列表仿函数实例中使用 unsafeCoerce

haskell - 在 Haskell 中处理事件

scala - 在 Scala 中使用 def 定义字段是什么意思?

MongoDB 查询在集合中找不到文档

scala - 如何通过scala中类型参数的类型成员来约束参数?

multithreading - 纯函数式数据结构总是无锁的吗?

haskell - 如何在 Haskell 中编写事件总线?

haskell - 添加未使用的实例可修复类型错误

scala - 我可以更改scala中编译器给出的错误消息吗?

haskell - 如何判断一个 monad 是否可交换?