如何有意义地在类型中定义的scala中使用函数类型?

时间:2011-09-11 06:55:40

标签: scala

我是scala的新手和天真。只知道如何定义一个函数类型,例如Set here(仅作为示例)。

type Set = Int => Boolean 

def set(i: Int): Set = n => n == i 
def contains(s: Set, i: Int) = s(i)

我还阅读了与语言无关的函数类型的wiki。看来C#,C,Haskel也有类似的语法。 http://en.wikipedia.org/wiki/Function_type

我的问题是在哪种情况下你更喜欢定义这种抽象类型函数之一并使用它, 没有其他选择达到同一目标?比较使用def

直接定义具体方法

或者我可以放弃要求,说使用这个函数类型,我可以使代码看起来好多了。 这样我就可以更多地了解函数类型。

这里我主要感兴趣的部分是type Set = Int => Boolean,当你想抽象出来的时候?我正在寻找现实生活中的用例,以及如何在scala语法中的具体方法中实现它。 例如,这个有点复杂。

type Set2 = (Int,Int,String) => (Boolean  => Int) => (Boolean  => Int).

我知道它被称为更高级的类型。语法本身确实很有意义。 但我只需要scala初学者更简单的现实生活例子。

我发现这个答案描述了它。 What is a higher kinded type in Scala?

但对我来说它看起来仍然有点模糊。我更喜欢初学者的简单答案。 看起来函数本身除了参数和结果类型之外不需要任何其他任何实现方法。 例如,如果结果(布尔值)不是来自参数(Int),它仍然会编译。

def set(i: Int): Set1 = aa => new Date().getDate() == i 

我不是吗?

让我知道为什么这个问题不明确或不好,所以我可以改进它,先生!

3 个答案:

答案 0 :(得分:29)

Scala中的关键字type为给定类型创建别名。例如:

scala> type Str = String
defined type alias Str

scala> val greeting: Str = "Hello World!"
greeting: Str = Hello World!

这与你所做的非常相似:

scala> type Set = Int => Boolean
defined type alias Set

scala> val isEven: Set = _ % 2 == 0
isEven: Int => Boolean = <function1>

scala> println(isEven(4))
true

scala> println(isEven(5))
false

虽然类型别名有时可用于澄清目的,但文档不是它们的主要用例。 Scala的类型系统非常复杂。例如,有一种替代泛型,即抽象类型。考虑一下:

// Generics
abstract class GenericAbstraction[TypeArgument]
class GenericConcrete extends GenericAbstraction[String]

// Abstract types
abstract class TypeAbstraction {
   type TypeArgument
}
class TypeConcrete extends TypeAbstraction {
   type TypeArgument = String
}

这些代码示例基本上完成了同样的事情,但是在某些情况下您需要抽象类型,但不能(或不应该)使用泛型。您可以找到更多信息here

答案 1 :(得分:1)

您可以按如下方式定义函数文字:

val incrementor = (x: Int) => x + 1

或者如果你有一些可以被Scala类型推断使用的上下文,你可以使用简化形式,如:

val listOfInt = List(1, 2, 3, 4, 5)

listOfInt map {x => x + 1}
listOfInt map {_ + 1}

甚至

listOfInt map {1 +}

这些文字都暗示了类型本身,或者它们的类型受到传递给它们的高阶函数的预期类型的​​约束。

关于功能和方法之间的区别,有几个问题可能是很好的背景阅读,但也许看看Martin Odersky的书Programming in Scala (Version 1)的免费版本将是一个更好的阅读起点关于功能和方法。

答案 2 :(得分:0)

我正在考虑这样。类型中的函数定义是抽象的,这使得可以定义不同的具体方法来实现它们。我认为它被称为多态性或后来的绑定。 这使得以后可以在运行时绑定函数类型和具体方法。

我认为在JAVA中,你不能通过静态方法覆盖抽象方法。但在函数式语言中,定义实现抽象函数的具体方法似乎很自然。如果我错了,请纠正我。

看看这个“多态函数”。

http://gleichmann.wordpress.com/2011/01/23/functional-java-polymorphic-functions/

但结论是可悲的我。我们只能在scala中模拟它。请从链接中查看。

<哇>“哇,这是一个什么样的旅程。我们发现在Scala中直接定义多态函数是不可能的。相反,有一些工作可以模拟它们。这一切都归结为这样一个事实,即函数是一个值某个函数类型需要在运行时进行类型参数化,所有类型参数都需要进行类型参数化以获取实际值(或该类型的实例)。“

“所以作为最后的结论,定义多态函数是可能的,但后果可能会超过好处。一如既往,你需要意识到给定的风险,并自己决定是否值得权衡(我希望向你展示了你的具体问题......“