More haskell-like applicative syntax in scalaz

我与影子孤独终老i 提交于 2019-12-10 14:44:14

问题


I am experimenting with scalaz. I tried writing code in applicative code. I wrote code like this:

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

I didn't like this code very much. I would like to code which is closer to Haskell style, something like this:

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

Is this possible. And why scalaz didn't implement it this way?


回答1:


Scala's type inference, is much more limited than in Haskell (identifier overloading, which comes with the JVM being one of the reasons). Inferences flows from left to right, and the type of the arguments of a function may be deduced from previous context (if at the place of the definition, a function with arg type A is expected), but not from how they are used in the definition. Scalaz syntax makes the arguments types available. Reversing it would most of the time force you to write the function arguments types, e.g.

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



回答2:


You can translate the Haskell version directly into Scala, if you're willing to be a little more verbose:

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)

Or, as a one-liner:

val c = 2.some <*> 1.some.map(x => math.max(x, _: Int))

Or:

val c = 2.some <*> (1.some map (math.max _).curried)

The order is reversed because these are method calls instead of infix operators, but it's essentially the same thing as max <$> a <*> b: we map the function over the first item, and then apply the result to the second.



来源:https://stackoverflow.com/questions/11501981/more-haskell-like-applicative-syntax-in-scalaz

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!