More hackle-like applicative syntax in scalaz

I am experimenting with fairy tale. I tried writing code in applicative code. I wrote the code as follows:

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

I really did not like this code. I would like to introduce code that is closer to the Haskell style, something like this:

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

It is possible. And why did not the tale realize it in this way?

+5
source share
2 answers

The Scala output type is much more limited than in Haskell (identifier overloading, which is associated with the JVM, is one of the reasons). The conclusions go from left to right, and the type of function arguments can be inferred from the previous context (if at the place of definition a function with an argument of type A is assumed), but not on how they are used in the definition. Scalaz syntax allows the use of argument types. When accessing it, most of the time it will force you to write the types of function arguments, for example.

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

You can translate the Haskell version directly to Scala if you want 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 single line:

 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 essentially this is the same as max <$> a <*> b : we map the function to the first element, and then apply the result to the second.

+4
source

All Articles