簡體   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