【发布时间】:2020-07-15 14:26:20
【问题描述】:
假设谓词是一个函数 A => 布尔值,我想为谓词实现 Cats 的“逆变函子”类型类的实例。 我还有一个隐式类 PredicateOps,它为谓词定义联合和相交运算符。
我已经能够使用类型别名让实例工作:
type Predicate[A] = A => Boolean
implicit val predicateContra = new Contravariant[Predicate] {
override def contramap[A, B](fa: Predicate[A])(f: B => A): Predicate[B] =
(b: B) => fa(f(b))
}
但是当我这样做时,我必须像这样将所有谓词函数强制转换为别名:
val even: Predicate[Int] = (i: Int) => i % 2 == 0
我觉得很烦人。所以我想知道,除了使用类型别名,我是否可以直接为从类型变量 A 到布尔值的 Function1 定义 predicateContra,但我无法让它工作。以下两个想法都给我一个编译器错误:
implicit val predicateContra = new Contravariant[Function1[_, Boolean]] {
// "Function1[_, Boolean] takes no type parameters, expected: one"
implicit def predicateContra[A] = new Contravariant[Function1[A, Boolean]] {
// "A => Boolean takes no type parameters, expected: one"
我如何告诉编译器我的 Function1 的第一个参数应该保持一个“洞”,而第二个应该固定为布尔值?这甚至可能吗? 查看猫的源代码,我在很多地方发现了星号作为类型参数,但这对我也不起作用。
【问题讨论】:
-
如果我理解正确,您正在寻找这样的东西:```implicit def predicateContra = new Contravariant[Function1[*, Boolean]] { override def contramap[A, B](fa : 谓词[A])(f: B => A): 谓词[B] = (b: B) => fa(f(b)) } ``
-
如果您只想忽略 Function1 的输入类型,您可以使用 *(星号)scastie.scala-lang.org/Bunyod/vz1GI9IDTfa5XSOrb3Tmvw/10 我不确定它是否回答了您的问题?
标签: scala functional-programming functor scala-cats type-level-computation