官术网_书友最值得收藏!

Type lambdas

As a next step, let's imagine that we have a generic Filler that is capable of filling different containers with different kinds of contents, as shown in the following code snippet:

sealed trait Contents
case class Water(purity: Int) extends Contents
case class Whiskey(label: String) extends Contents

sealed trait Container[C] { def contents: C }
case class Glass[C](contents: C) extends Container[C]
case class Jar[C](contents: C) extends Container[C]

sealed trait Filler[C <: Contents, CC <: Container[C]] {
def fill(c: C): CC
}

What could we do if we had a requirement to provide a method that should only accept one type of container or content? We would need to fix the second type parameter in a similar fashion to how we would partially apply a function if given one of the arguments. A type alias can be used to do this on the type level:

type WaterFiller[CC <: Container[Water]] = Filler[Water, CC]

def fillWithWater[CC <: Container[Water]](container: CC)(filler: WaterFiller[CC]) = ???

But it feels a bit verbose to define a type alias just to be used once in the definition of the function parameter. Type lambda is a syntax that allows us to do such partial type application in-place:

def fillWithWater[CC <: Container[Water], F: ({ type T[C] = Filler[Water, C] })#T[CC]](container: CC)(filler: F) = ???

The type lambda can also be used to define a parameter type directly:

def fillWithWater[CC <: Container[Water]](container: CC)(filler: ({ type T[C] = Filler[Water, C] })#T) = ???

The internal definition of T[C] is analogous to the type alias we defined previously. The added part is the type projection, ()#T[C], that allows us to reference the type we've just defined.

主站蜘蛛池模板: 洛隆县| 稻城县| 丰台区| 南丰县| 论坛| 凭祥市| 洪江市| 阿合奇县| 江津市| 宣恩县| 南溪县| 板桥市| 昌吉市| 平安县| 石泉县| 漾濞| 农安县| 扶余县| 惠安县| 凌云县| 石屏县| 蛟河市| 龙南县| 白山市| 钟祥市| 梁山县| 井研县| 抚州市| 扬州市| 竹北市| 平邑县| 高碑店市| 怀集县| 延边| 东阳市| 通榆县| 巴楚县| 堆龙德庆县| 邛崃市| 利辛县| 洮南市|