带函子的数值映射
Numeric Map Over With Functor
我想将 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
中的参数类型固定为数字。我该如何解决?谢谢
代码片段,
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
谢谢 Mario 和 Dmytro 的回答。
Dmytro,你的答案与我在 https://users.scala-lang.org/t/how-to-add-type-constraint-to-functors-map-function/2055 中找到的完全一样。我放弃约束或使用约束 Functor 是有道理的。我接受了 Mario 的回答,因为它向我展示了一个替代解决方案,因为 Functor 是不可能的。
无法为任何类型构造函数定义 Functor
类型 class 的实例。
类型构造函数 F[_]
具有类型 class Functor
的实例这一事实意味着 对于任何 A
、B
,有一个函数A => B
,你知道如何将F[A]
转换为F[B]
。
但是如何将 Bonus[A]
转换为 Bonus[B]
对于任何 A
, B
?
类型 Bonus[A]
、Bonus[B]
对任何 A
、B
都有意义,即使它们不是 Numeric
,但会创建 Bonus[B]
通过构造函数仅对 B: Numeric
.
有意义
要么删除 case class Bonus[A: Numeric](amt: A)
中的上下文绑定 Numeric
,要么 Bonus
不是 Functor
。
如果您定义自己的类型class
trait NumericFunctor[F[_]] {
def fmap[A: Numeric, B: Numeric](fa: F[A])(f: A => B): F[B]
}
它不是针对类型类别的标准函子,而是针对 Numeric
类型类别的自定义函子。
尝试
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)
请注意我们如何通过
让我们的类型类解决方案意识到 A
和 B
的进一步界限
(implicit ga: G[A], gb: G[B])
我想将 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
中的参数类型固定为数字。我该如何解决?谢谢
代码片段,
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
谢谢 Mario 和 Dmytro 的回答。
Dmytro,你的答案与我在 https://users.scala-lang.org/t/how-to-add-type-constraint-to-functors-map-function/2055 中找到的完全一样。我放弃约束或使用约束 Functor 是有道理的。我接受了 Mario 的回答,因为它向我展示了一个替代解决方案,因为 Functor 是不可能的。
无法为任何类型构造函数定义 Functor
类型 class 的实例。
类型构造函数 F[_]
具有类型 class Functor
的实例这一事实意味着 对于任何 A
、B
,有一个函数A => B
,你知道如何将F[A]
转换为F[B]
。
但是如何将 Bonus[A]
转换为 Bonus[B]
对于任何 A
, B
?
类型 Bonus[A]
、Bonus[B]
对任何 A
、B
都有意义,即使它们不是 Numeric
,但会创建 Bonus[B]
通过构造函数仅对 B: Numeric
.
要么删除 case class Bonus[A: Numeric](amt: A)
中的上下文绑定 Numeric
,要么 Bonus
不是 Functor
。
如果您定义自己的类型class
trait NumericFunctor[F[_]] {
def fmap[A: Numeric, B: Numeric](fa: F[A])(f: A => B): F[B]
}
它不是针对类型类别的标准函子,而是针对 Numeric
类型类别的自定义函子。
尝试
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)
请注意我们如何通过
让我们的类型类解决方案意识到A
和 B
的进一步界限
(implicit ga: G[A], gb: G[B])