为什么斯卡拉的类型推断没有Haskell那么强大? [英] Why is Scala's type inference not as powerful as Haskell's?

查看:84
本文介绍了为什么斯卡拉的类型推断没有Haskell那么强大?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Haskell的类型推理引擎比Scala更强大。在Haskell中,我很少需要明确写出类型,而在Scala中,类型只能在表达式中推断,而不能在方法定义中推断。

例如,请参阅以下Haskell代码片段:

 大小xs =循环xs 0 
其中
循环[] acc = acc
循环(_:xs)acc =循环xs(acc + 1)

名单。 Haskell编译器可以识别使用哪些类型以及函数定义是什么。等价的Scala代码:

  def size [A]:List [A] => Int = xs => {
def loop:(List [A],Int)=> Int = {
case(Nil,acc)=> acc
case(_ :: xs,acc)=>循环(xs,acc + 1)
}
循环(xs,0)
}

或者使用方法定义:

$ $ $ $ $ $ c $ def size [A](xs:List [A])= {
def loop(xs:List [A],acc:Int):Int = xs match {
case Nil => acc
case _ :: xs =>循环(xs,acc + 1)
}
循环(xs,0)
}

我的问题是:为什么我不能像下面这样写他们?

  def size = xs => {
def loop = {
case(Nil,acc)=> acc
case(_ :: xs,acc)=>循环(xs,acc + 1)
}
循环(xs,0)
}

再一次使用方法定义:

  def size(xs)= {
def loop (xs,acc)= xs match {
case Nil => acc
case _ :: xs =>循环(xs,acc + 1)
}
循环(xs,0)
}

是否因为没有人实现它?这种情况下,Scala的类型系统是否不够强大?或者还有其他的原因吗?

解决方案

主要原因是Scala的类型系统允许子分类, Hindley-Milner类型推断算法不支持。



Haskell没有子类型输入,所以算法在那里效果更好,尽管GHC支持的许多受欢迎的类型系统扩展导致类型推断再次失败,迫使您为某些类型提供显式类型签名表达式。



最后,它是类型系统的功能和可以完成的类型推断的量之间的折衷。斯卡拉和哈斯克尔只是做了不同的权衡。

The type inference engine of Haskell is much more powerful than Scala's. In Haskell I rarely have to explicitly write the types whereas in Scala the types can only be inferred in expressions but not in method definitions.

For example, see following Haskell code snippet:

size xs = loop xs 0
  where
    loop [] acc = acc
    loop (_ : xs) acc = loop xs (acc+1)

It returns the size of a List. The Haskell compiler can recognize what types are used and what the function definition is. The equivalent Scala code:

def size[A]: List[A] => Int = xs => {
  def loop: (List[A], Int) => Int = {
    case (Nil, acc) => acc
    case (_ :: xs, acc) => loop(xs, acc+1)
  }
  loop(xs, 0)
}

Or with method definitions:

def size[A](xs: List[A]) = {
  def loop(xs: List[A], acc: Int): Int = xs match {
    case Nil => acc
    case _ :: xs => loop(xs, acc+1)
  }
  loop(xs, 0)
}

My question is: Why can't I write them like the following?

def size = xs => {
  def loop = {
    case (Nil, acc) => acc
    case (_ :: xs, acc) => loop(xs, acc+1)
  }
  loop(xs, 0)
}

Once again with method definitions:

def size(xs) = {
  def loop(xs, acc) = xs match {
    case Nil => acc
    case _ :: xs => loop(xs, acc+1)
  }
  loop(xs, 0)
}

Is it because nobody has implemented it yet? Is the type system of Scala not as powerful as needed for this case? Or are there other reasons?

解决方案

The main reason is that the type system of Scala allows sub-typing, which the Hindley-Milner type inference algorithm does not support.

Haskell does not have sub-typing, so the algorithm works much better there, although many popular type system extensions supported by GHC cause type inference to fail again, forcing you to provide explicit type signatures for some expressions.

In the end, it's a trade-off between the power of the type system and the amount of type inference that can be done. Scala and Haskell have simply made different trade-offs.

这篇关于为什么斯卡拉的类型推断没有Haskell那么强大?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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