Is it possible to implement flip in Scala like it is implemented in Haskell?
http://hackage.haskell.org/package/base-4.7.0.1/docs/src/GHC-Base.html#flip
flip :: (a -> b -> c) -> b -> a -> c
flip f x y = f y x
Well, this is a fairly literal translation:
def flip[A, B, C](f: A => B => C)(x: B)(y: A) = f(y)(x)
Now you can write the following:
scala> def append: String => String => String = a => a + _
append: String => (String => String)
scala> append("foo")("bar")
res0: String = foobar
scala> val flipped = flip(append) _
flipped: String => (String => String) = <function1>
scala> flipped("foo")("bar")
res1: String = barfoo
You could argue that the following is a little closer to the spirit of the Haskell version:
def flip[A, B, C](f: A => B => C): B => A => C = x => y => f(y)(x)
Now you don't have to eta-expand the partially-applied method:
scala> val flipped = flip(append)
flipped: String => (String => String) = <function1>
scala> flipped("foo")("bar")
res2: String = barfoo
So you've got a couple of choices. It's not really clear that one is more like the Haskell implementation, but given the distinction that Scala makes between methods and functions they're both pretty close.
Another way, more closer to Haskell version:
scala> def flip[a, b, c]: (a => b => c) => b => a => c = f => x => y => f(y)(x)
flip: [a, b, c]=> (a => (b => c)) => (b => (a => c))
scala> val f: Int => Char => String = i => c => f"Int($i) and Char($c)"
f: Int => (Char => String) = <function1>
scala> val g = flip(f)
g: Char => (Int => String) = <function1>
Or this:
scala> def flip[a, b, c]: (a => b => c) => b => a => c = {
| case f => x => y => f(y)(x)
| }
flip: [a, b, c]=> (a => (b => c)) => (b => (a => c))
scala> g('a')(100)
res0: String = Int(100) and Char(a)
scala> f(100)('a')
res1: String = Int(100) and Char(a)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With