【问题标题】:Numeric Map Over With Functor带有函子的数值映射
【发布时间】:2019-11-30 05:19:12
【问题描述】:

我想将case class Bonus[A: Numeric](amt: A) 映射到 Functor 上,但它失败了。编译错误是

Error:(157, 69) could not find implicit value for evidence parameter of type Numeric[B] (No implicit Ordering defined for B.)
override def fmap[A, B](fa: Bonus[A])(f: A => B): Bonus[B] = Bonus(f(fa.amt))

一般情况下,我想将Bonus 中的参数类型固定为数字。我该如何解决这个问题?谢谢

代码sn-p,

trait Functor[F[_]] {
  def fmap[A, B](fa: F[A])(f: A => B): F[B]
}

def fmap[A, B, F[_]](fa: F[A])(f: A => B)(implicit ev: Functor[F]): F[B] = ev.fmap(fa)(f)

case class Bonus[A: Numeric](amt: A)

implicit val bonusFunctor = new Functor[Bonus] {
  override def fmap[A, B](fa: Bonus[A])(f: A => B): Bonus[B] = Bonus(f(fa.amt)) // error
}

fmap(Bonus(123))(_ * 2)

更新 1

感谢 MarioDmytro 的回答。

Dmytro,您的答案与我在https://users.scala-lang.org/t/how-to-add-type-constraint-to-functors-map-function/2055 找到的完全一样。要么我放弃约束,要么我使用约束 Functor,这是有道理的。我接受了 Mario 的回答,因为它向我展示了另一种解决方案,因为 Functor 无法实现。

【问题讨论】:

  • 我认为问题在于B 没有Numeric[B] 的隐式转换,这是您的Bonus 课程所要求的

标签: scala typeclass functor


【解决方案1】:

Functor 类型类的实例不能为任何类型构造函数定义。

类型构造函数F[_] 具有类型类Functor 的实例这一事实意味着对于任何AB,具有函数A => B,你知道如何转换F[A]F[B]

但是如何将Bonus[A] 转换为Bonus[B] 对于任何AB

类型Bonus[A]Bonus[B] 对任何AB 都有意义,即使它们不是Numeric,但通过构造函数创建Bonus[B] 的新实例仅对B: Numeric 有意义。

case class Bonus[A: Numeric](amt: A)Bonus 中删除上下文绑定的Numeric 不是Functor

如果你定义自己的类型类

trait NumericFunctor[F[_]] {
  def fmap[A: Numeric, B: Numeric](fa: F[A])(f: A => B): F[B]
}

它将不是类型类别上的标准函子,而是Numeric 类型类别上的自定义函子。

【讨论】:

    【解决方案2】:

    试试

    trait GFunctor[F[_], G[_]] {
      def fmap[A, B](fa: F[A])(f: A => B)(implicit ga: G[A], gb: G[B]) : F[B]
    }
    
    def fmap[A, B, F[_], G[_]](fa: F[A])(f: A => B)(implicit ev: GFunctor[F, G], ga: G[A], gb: G[B]): F[B] = ev.fmap(fa)(f)
    
    case class Bonus[A: Numeric](amt: A)
    
    implicit val bonusFunctor = new GFunctor[Bonus, Numeric] {
      override def fmap[A, B](fa: Bonus[A])(f: A => B)(implicit numA: Numeric[A], numbB: Numeric[B]): Bonus[B] = Bonus(f(fa.amt))
    }
    
    fmap(Bonus(123))(_ * 2)
    

    哪个输出

    res0: Bonus[Int] = Bonus(246)
    

    请注意我们是如何让我们的 typeclass 解决方案通过

    了解AB 的进一步界限
    (implicit ga: G[A], gb: G[B])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-12-27
      • 1970-01-01
      • 1970-01-01
      • 2015-06-01
      • 2014-12-27
      • 2022-12-17
      • 2021-08-03
      相关资源
      最近更新 更多