在“ 使用Scala进行功能编程”课程的一项作业中,引入了一种称为Terrain的类型-Terrain表示一个区域,该区域的某些部分可以访问,而某些部分则不能访问。 因此,以一种非常聪明的方式在任务中以下列方式定义了Terrain:
case class Pos(x:Int, y: Int)type Terrain = Pos => Boolean
本质上讲,Terrain是一个函数,它需要一个位置,并且该位置根据该位置是否可访问而返回布尔值!
鉴于对地形的这种定义,可以通过以下方式定义一种可以访问每个位置的“无限”地形的方法:
val infiniteTerrain = (pos: Pos) => true
或其他可以访问某些坐标的地形可以通过以下方式进行定义:
def terrainFunction(vector: Vector[Vector[Char]]) : Terrain = {(pos: Pos) => {if (pos.x > vector.size - 1 || pos.y > vector(0).size - 1 || pos.x < 0 || pos.y < 0) {false} else {val ch = vector(pos.x)(pos.y)ch == 'o';}}
} val terrain1 = terrainFunction(Vector(Vector('-','-','-'),Vector('-','o','-'),Vector('-','o','-'),Vector('-','o','-'),Vector('-','-','-')))
一切都非常聪明。
现在,考虑到即将发布Java 8 ,可以使用Java 8构造尝试同样(几乎:-))的聪明代码:
尽管Terrain可以在Scala中定义为功能签名,但必须将其定义为Java 8的功能接口:
interface Terrain {public boolean isAccessible(Pos pos);
}
给定此接口,使用Java 8中的Lambdas可以看到无限地形:
Terrain infiniteTerrain = (pos) -> true;
可以通过以下几行定义Java 8中等效的terrainFunction:
public Terrain terrainFunction(char[][] arr) {return (pos) -> {if (pos.x > arr.length - 1 || pos.y > arr[0].length - 1 || pos.x < 0 || pos.y < 0) {return false;} else {char ch = arr[pos.x][pos.y];return ch == 'o';}};
}char[][] arr = {{'-','-','-'},{'-','o','-'},{'-','o','-'},{'-','o','-'},{'-','-','-'}
};
Terrain terrain = terrainFunction(arr); assertTrue(terrain.isAccessible(new Pos(1, 1)));
足够近!
翻译自: https://www.javacodegeeks.com/2014/03/java-8-functional-interfaces-random-musings-implementing-a-scala-type.html