为什么curala中没有隐含的currying和uncurrying

时间:2010-08-11 11:54:26

标签: scala functional-programming currying implicit-conversion

如果我有一个功能:

f : A => B => C

我可以定义一个隐式转换,以便在需要函数(A, B) => C时使用。这也是另一个方向。

为什么这些转换不是隐式(或隐式可用)?我假设某些坏事可能会发生糟糕的事情。这有什么价值?

2 个答案:

答案 0 :(得分:12)

我认为不会发生任何不好的事情。转换完全明确。最糟糕的情况是,Scala无法确定隐式转换是否适用。

implicit def curryImplicitly[A,B,C](f: (A, B) => C) =
  (a: A) => (b: B) => f(a, b)
implicit def uncurryImplicitly[A,B,C](f: A => B => C) =
  (a: A, b: B) => f(a)(b)

然后,这些也会有所帮助。

implicit def flipImplicitly[A,B,C](f: (A, B) => C) =
  (b: B, a: A) => f(a, b)
implicit def flipImplicitlyCurried[A,B,C](f: A => B => C) =
  (b: B) => (a: A) => f(a)(b)

但那些不是传递性的,所以你需要这些:

implicit def flipAndCurry[A,B,C](f: (A, B) => C) =
  (b: B) => (a: A) => f(a, b)
implicit def flipAndUncurry[A,B,C](f: A => B => C) =
  (b: B, a: A) => f(a)(b)

但现在转换是模棱两可的。所以它不是所有的玫瑰。

让我们知道它在实践中是如何运作的。您可能需要Function3,Function4等的等效项

答案 1 :(得分:8)

默认情况下你不希望它们隐式可用(永远在线),因为当你用一堆相似类型的参数重载时,类型系统很难帮你解决:

A => B => C
D => C      // D is allowed to be a tuple (A,B)...

(A,B) => C  // If I have this, to whom should I convert?

强力打字的部分优势是在你做了一些愚蠢的事情时警告你。努力工作会让事情变得更有效。在这里,如果转换是自动完成的,您可能无法调用您打算调用的方法。

根据要求隐含地提供它们很好,但如果你需要的话,自己做的并不难。这是我很少使用的东西;我不会把它放在我的前十名中,或者甚至可能是我在图书馆中需要的上百件事情(部分因为我可能更喜欢自动转换为元组而不是自动curry / uncurrying)。