在scalaz中更像haskell的应用语法

时间:2012-07-16 09:53:53

标签: scala scalaz

我正在尝试使用scalaz。我尝试在应用代码中编写代码。我写了这样的代码:

val max: Option[Int] = (a |@| b) { math.max(_, _) }

我不太喜欢这段代码。我想编写更接近Haskell风格的代码,如下所示:

val max: Option[Int] = { math.max(_, _) } <$> a <*> b

这可能吗?为什么scalaz没有这样实现呢?

2 个答案:

答案 0 :(得分:7)

Scala的类型推断比Haskell更有限(标识符重载,其中JVM是其中一个原因)。推理从左向右流动,并且函数的参数类型可以从先前的上下文推导出来(如果在定义的位置,预期具有arg类型A的函数),而不是从它们如何在定义。 Scalaz语法使参数类型可用。反转它会大部分时间强制你编写函数参数类型,例如

{math.max(_: Int, _: Int) } <$> a <*> b

答案 1 :(得分:4)

可以将Haskell版本直接翻译成Scala,如果你愿意更加冗长:

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基本相同:我们将函数映射到第一个项目,然后将结果应用于第二