函子上的数字映射 [英] Numeric Map Over With Functor

查看:90
本文介绍了函子上的数字映射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在函子上映射case class Bonus[A: Numeric](amt: A),但失败.编译错误是

I want to map case class Bonus[A: Numeric](amt: A) over a Functor and it fails. The compilation error is

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中的参数类型固定为数字.我该如何解决?谢谢

In general, I want to fix the parameter type in Bonus to numbers. How do I do fix that? Thanks

代码段

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

谢谢您马里奥& Dmytro 为您提供答案.

Update 1

Thank you Mario & Dmytro for your answers.

Dmytro,您的答案与我在

Dmytro, your answer is precisely as what I found at https://users.scala-lang.org/t/how-to-add-type-constraint-to-functors-map-function/2055. It makes sense that either I drop the constraint or I use a constraint Functor. I accepted Mario's answer because it shows me an alternative solution because it is not possible with Functor.

推荐答案

尝试

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)

请注意,我们如何通过

(implicit ga: G[A], gb: G[B])

这篇关于函子上的数字映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆