首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Cats:为没有类型别名的谓词实现逆变?

Cats:为没有类型别名的谓词实现逆变?
EN

Stack Overflow用户
提问于 2020-04-03 20:04:51
回答 1查看 207关注 0票数 0

假设一个谓词是一个函数=>布尔值,我想为谓词实现一个Cats的"Contravariant Functor“类型类的实例。我还有一个隐式类PredicateOps,它定义了谓词的并集和交集运算符。

我已经能够使用类型别名让实例工作:

代码语言:javascript
复制
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))
}

但当我这样做时,我必须将所有谓词函数强制化为别名,如下所示:

代码语言:javascript
复制
val even: Predicate[Int] = (i: Int) => i % 2 == 0

我觉得这很烦人。因此,我想知道是否可以直接为Function1定义从类型变量A到布尔值的predicateContra,而不是使用类型别名,但我无法让它工作。下面这两个想法都给了我一个编译器错误:

代码语言:javascript
复制
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的第一个参数应该保持为一个“洞”,而第二个参数应该被修复为布尔值?这有可能吗?看一下猫的源代码,我发现星号在很多地方都是类型参数,但这对我来说也不起作用。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-03 20:44:49

你可以使用kind projector,它允许你用一个星号(*)来表示“类型孔”。

这使得可以使用非常简单的语法来定义一种类型的* -> *,即一元类型构造函数(接受单个类型来生成类型)。例如,可以简单地将采用某个类型A来生成类型Map[A, Int]的类型编写为Map[*, Int]

那么你的代码就变成了:

代码语言:javascript
复制
val strToBool: String => Boolean = _.contains("1")
val intToStr: Int => String = _.toString

def predicateContra = 
  new Contravariant[Function1[*, Boolean]] {
    override def contramap[A, B](fa: A => Boolean)(f: B => A): B => Boolean = 
      (b: B) => fa(f(b))
  }

predicateContra.contramap(strToBool)(intToStr)(42) // false 
predicateContra.contramap(strToBool)(intToStr)(41) // true

如果你不想使用额外的库,你可以在普通的Scala中通过使用lambda类型以一种更丑陋的方式来实现:

代码语言:javascript
复制
def predicateContra =
  new Contravariant[({ type lambda[A] = Function1[A, Boolean] })#lambda] {
      ...
  }
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61011524

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档