我与scalaz试验。 我试图在应用性代码编写代码。 我写了这样的代码:
val max: Option[Int] = (a |@| b) { math.max(_, _) }
我不喜欢这样的代码非常多。 我想代码更接近Haskell的风格,这样的事情:
val max: Option[Int] = { math.max(_, _) } <$> a <*> b
这可能吗。 为什么scalaz没有实现这种方式?
我与scalaz试验。 我试图在应用性代码编写代码。 我写了这样的代码:
val max: Option[Int] = (a |@| b) { math.max(_, _) }
我不喜欢这样的代码非常多。 我想代码更接近Haskell的风格,这样的事情:
val max: Option[Int] = { math.max(_, _) } <$> a <*> b
这可能吗。 为什么scalaz没有实现这种方式?
Scala的类型推断,比在Haskell(标识符重载,附带了JVM是原因之一)有限得多。 推论流从左到右,和的函数的参数的类型可以从先前上下文推导出(如果在定义的位置,用Arg类型A的功能被预期),但不能从它们是如何在所使用的定义。 Scalaz语法使参数类型可用。 倒车,将大部分时间力的,你写的函数参数类型,例如
{math.max(_: Int, _: Int) } <$> a <*> b
您可以直接翻译哈斯克尔版本为斯卡拉,如果你愿意是一个小更详细:
import scalaz._, Scalaz._
val a = Option(1)
val b = Option(2)
val f: Int => Int => Int = x => math.max(x, _)
val c = b <*> (a map f)
或者,作为一个班轮:
val c = 2.some <*> 1.some.map(x => math.max(x, _: Int))
要么:
val c = 2.some <*> (1.some map (math.max _).curried)
顺序是相反的,因为这些都是方法调用,而不是中缀操作符,但它本质上是一回事max <$> a <*> b
:我们绘制了第一项功能,然后将结果应用到第二位。