简体   繁体   English

使用函数文字输入推理

[英]Type inference with function literals

I am trying currently trying to solve some Scala problem set for getting to know with the language. 我正在尝试解决一些Scala问题集 ,以便用该语言来了解。 I am stuck with problem 11 where my solution will not compile. 我遇到问题11,我的解决方案无法编译。 My question is: Why is this illegal in Scala? 我的问题是:为什么Scala中这是非法的?

def countPackSingle[A](list: List[A]): List[Any] = {
  pack(list) map {ls => {
    case head :: Nil => head
    case head :: tail => List(tail.size + 1, head)
  }}
}

IntelliJ is happy about this definition, but the compiler complains: IntelliJ很高兴这个定义,但编译器抱怨:

missing parameter type for expanded function 缺少扩展函数的参数类型
The argument types of an anonymous function must be fully known. 必须完全知道匿名函数的参数类型。 (SLS 8.5) (SLS 8.5)

Expected type was: ? 预期的类型是:?

 pack(list) map {ls => { ^ 

I do not really get what this message is trying to tell me. 我真的没有得到这条消息试图告诉我的内容。 Can the scala compiler not infere the type of ls ? scala编译器可以不推断ls的类型吗? When I specify the type by ls: List[A] , the problem however remains. 当我通过ls: List[A]指定类型时,问题仍然存在。

At this occasion: Why can I specify the type for the argument ls when using curly braces { } but not when using parenthesises ( ) ? 在这种情况下:为什么我可以在使用花括号{ }时指定参数ls的类型,而不是在使用parenthesises ( ) Until today, I am looking for a good resource explaining the difference in Scala. 直到今天,我正在寻找一个很好的资源来解释Scala的不同之处。 So far, I believed it only makes a real difference when using the literals to create parial functions via `case and on some other rare occasions. 到目前为止,我认为在使用文字通过`case和其他一些罕见的场合创建parial函数时 ,它只会产生真正的不同

Thanks for help! 感谢帮助!

This structure: 这个结构:

{
  case head :: Nil => head
  case head :: tail => List(tail.size + 1, head)
}

is a syntactic sugar for a partial function, that's why compiler throws you this message, scalac thinks that you are trying to make a PartilFunction[List[A], List[A]] . 是一个部分函数的语法糖,这就是为什么编译器会抛出这个消息,scalac认为你正在尝试创建一个PartilFunction[List[A], List[A]] To fix this issue you have three ways: 要解决此问题,您有三种方法:

1) Complete this to pattern matching construct: 1)完成此模式匹配构造:

pack(list) map { ls => ls match {
    case head :: Nil => head
    case head :: tail => List(tail.size + 1, head)
  }
}

2) Use underscore syntax: 2)使用下划线语法:

pack(list) map { _ match {
    case head :: Nil => head
    case head :: tail => List(tail.size + 1, head)
  }
}

which is actually the same. 这实际上是一样的。 Now, if you want, you can ascribe a type for ls, but scala can successfully infer it. 现在,如果你愿意,你可以为ls归类一个类型,但是scala可以成功地推断它。

3) Use inline syntax: 3)使用内联语法:

pack(list) map {
  case head :: Nil => head
  case head :: tail => List(tail.size + 1, head)
}

It is possible because PartialFunction is a subclass of Function , so it is possible to use partial function directly instead of plain function. 这是可能的,因为PartialFunctionFunction的子类,因此可以直接使用partial函数而不是plain函数。

And you have no point in the result type List[Any] . 你在结果类型List[Any]没有任何意义。 1) this type is not good, cause you loose all your type information and 2) you function is not tailrecursive, so you can drop it and let scalac infer it for you 1)这种类型不好,导致你丢失所有的类型信息和2)你的功能不是tailrecursive,所以你可以删除它,让scalac推断它为你

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM