繁体   English   中英

在返回类型中捕获类型类

[英]Capture type class in returning type

在下面的示例中,我必须重复说M是一个Monad以便定义bar ,这似乎是不必要的,因为我已经在定义fnc告诉了编译器。

import scalaz._
import scalaz.Scalaz._

object MyTest {

  // function returning a function accepting a monad as parameter
  def fnc[M[_]: Monad, T](t: T): (M[T] => T) = xs => t

  // this works
  def bar[M[_]: Monad]: (M[Double] => Double) = fnc(1.0)

  // I would like this also to work
  val foo = fnc(1.0)
}

如何使foo为可以接受M[T]的函数?

Scala没有多态函数-任何函数值的输入和输出类型都必须是具体类型(但是,您可以具有返回函数的多态方法,并且fncbar都是此类的示例)。 这意味着您的foo定义仅在您指定具体的单子类型时才有效:

val foo: List[Double] => Double = fnc(1.0)

Shapeless将对象和隐式一起使用以实现多态函数值:

import scalaz._, Scalaz._

object foo extends shapeless.Poly1 {
  implicit def double[M[_]: Monad]: Case.Aux[M[Double], Double] = at(_ => 1.0)
}

接着:

scala> foo(List(1.0))
res0: Double = 1.0

scala> foo(Option(1.0))
res1: Double = 1.0

scala> foo(1.0: Id[Double])
res2: Double = 1.0

但是不幸的是,由于语言的限制,在如何定义这些多态函数值方面存在很多限制(例如,将1.0部分设置为参数很困难),因此通常最好还是多态方法起作用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM