是否可以像在Haskell中实现的那样在Scala中实现翻转?

时间:2014-08-17 13:19:35

标签: scala haskell

是否可以像在Haskell中实现的那样在Scala中实现翻转?

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

2 个答案:

答案 0 :(得分:7)

嗯,这是一个相当字面的翻译:

def flip[A, B, C](f: A => B => C)(x: B)(y: A) = f(y)(x)

现在您可以写下以下内容:

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

你可以说下面的内容更接近Haskell版本的精神:

def flip[A, B, C](f: A => B => C): B => A => C = x => y => f(y)(x)

现在你不必逐步扩展部分应用的方法:

scala> val flipped = flip(append)
flipped: String => (String => String) = <function1>

scala> flipped("foo")("bar")
res2: String = barfoo

所以你有几个选择。它不是很清楚,一个更像是Haskell的实现,但鉴于Scala在方法和函数之间的区别,它们都非常接近。

答案 1 :(得分:3)

另一种方式,更接近Haskell版本:

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>

或者这个:

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)