我正在阅读和学习使用类型类,我在Shapeless指南中发现了一种定义类型类的方法:
以下是示例:
我的问题是,这是如何工作的?我不明白为什么需要apply方法?
编辑:我看到一篇博客文章,描述创建类型类的步骤如下:
1.定义类型类合同trait Foo。
2.定义一个伴生对象Foo,其中有一个类似于implicitly的helper方法apply,以及一种通常从函数中定义Foo实例的方式。
3.定义FooOps类,定义一元或二元运算符。
4.定义FooSyntax trait,它从Foo实例隐式提供FooOps。
那么第2、3和4点是什么意思呢?
以下是示例:
object CsvEncoder {
// "Summoner" method
def apply[A](implicit enc: CsvEncoder[A]): CsvEncoder[A] =
enc
// "Constructor" method
def instance[A](func: A => List[String]): CsvEncoder[A] =
new CsvEncoder[A] {
def encode(value: A): List[String] =
func(value)
}
// Globally visible type class instances
}
我不理解的是apply方法的必要性?在上下文中它是做什么的?
之后,该指南描述了我如何创建一个类型类实例:
implicit val booleanEncoder: CsvEncoder[Boolean] =
new CsvEncoder[Boolean] {
def encode(b: Boolean): List[String] =
if(b) List("yes") else List("no")
}
实际上缩短为:
implicit val booleanEncoder: CsvEncoder[Boolean] =
instance(b => if(b) List("yes") else List("no"))
我的问题是,这是如何工作的?我不明白为什么需要apply方法?
编辑:我看到一篇博客文章,描述创建类型类的步骤如下:
1.定义类型类合同trait Foo。
2.定义一个伴生对象Foo,其中有一个类似于implicitly的helper方法apply,以及一种通常从函数中定义Foo实例的方式。
3.定义FooOps类,定义一元或二元运算符。
4.定义FooSyntax trait,它从Foo实例隐式提供FooOps。
那么第2、3和4点是什么意思呢?