理解`单形态'无形的例子

Kev*_*ith 6 scala shapeless

无形特性概述显示下面的例子:

import poly._

// choose is a function from Sets to Options with no type specific cases
object choose extends (Set ~> Option) {
  def apply[T](s : Set[T]) = s.headOption
}

scala> choose(Set(1, 2, 3))
res0: Option[Int] = Some(1)

scala> choose(Set('a', 'b', 'c'))
res1: Option[Char] = Some(a)
Run Code Online (Sandbox Code Playgroud)

但是,由于缺乏对Shapeless的经验,我不了解它与以下内容之间的区别:

scala> def f[T](set: Set[T]): Option[T] = set.headOption
f: [T](set: Set[T])Option[T]

scala> f( Set(1,2,3) )
res0: Option[Int] = Some(1)

scala> f( Set('a', 'b', 'c') )
res1: Option[Char] = Some(a)
Run Code Online (Sandbox Code Playgroud)

gzm*_*zm0 9

这里的重要区别是,这choose是一个可以作为值传递的函数.f由于Scala不支持多态函数值,因此无法创建(合理)值:

scala> val fun = f _
fun: Set[Nothing] => Option[Nothing] = <function1>
Run Code Online (Sandbox Code Playgroud)

如您所见,Scala修复了元素类型以Nothing使该函数对非空集无效:

scala> fun(Set(1))
<console>:10: error: type mismatch;
 found   : Int(1)
 required: Nothing
              fun(Set(1))
                      ^
Run Code Online (Sandbox Code Playgroud)

这可以像您期望的无形方法一样工作.