【问题标题】:How to add type constraint to functors map function如何向函子映射函数添加类型约束
【发布时间】:2017-12-08 08:31:48
【问题描述】:

我无法为具有类型约束的abstract class Foo[V : Monoid] 定义Functor。这是因为Functormap 方法采用B 参数而不是Monoid

我的问题是如何以及在哪里添加这样的约束?

这是我正在尝试做的一个示例:

import cats.Functor
import cats.kernel.Monoid

abstract class Foo[A : Monoid] {
  val a: A
}

object Foo {
  implicit def FooFunctor = new Functor[Foo] {
    override def map[A, B](fa: Foo[A])(f: (A) => B) = new Foo[B] {
      override val a: B = f(fa.a)
    }
  }
}

这会引发以下异常:

Error:(12, 59) could not find implicit value for evidence parameter of type cats.kernel.Monoid[B]
    override def map[A, B](fa: Foo[A])(f: (A) => B) = new Foo[B] {

我的第一个解决方案是在 map 定义 (override def map[A, B : Monoid]) 中添加约束,但这不合法,因为这将更改 Functor 中函数的定义并引发异常:

Error:(12, 18) method map overrides nothing.

谁能帮我摆脱困境?任何建议将不胜感激。

【问题讨论】:

  • 这不是你需要Applicative 而不是Functor 的情况吗?这样你就可以用pure[Foo[B]]创建Foo[B]
  • 这看起来像一个典型的XY Problem。您能否描述一下您试图通过此代码解决的实际问题?根据cats 定义,您现在指定的Foo 不是Functor,因为必须在每个可能的类型上定义cats.Functor。但也许这不是你真正需要的。因此,请指定您的高级问题,有人可能会提出更好的解决方案。

标签: scala functor applicative type-level-computation


【解决方案1】:

我认为主要问题是您试图将子类型与类型类混合。应该是:

trait Foo[A] extends Monoid[A] with Functor[A] {
  val a: A
}

trait SomeADT
case class SomeValue(a: String) extends SomeADT

object SomeADT {
  //evidence
}

【讨论】:

  • 那仍然不完整。
猜你喜欢
  • 2011-12-17
  • 1970-01-01
  • 2023-01-29
  • 1970-01-01
  • 2019-03-21
  • 1970-01-01
  • 2012-09-06
  • 2021-09-23
  • 1970-01-01
相关资源
最近更新 更多