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

oxb*_*kes 13 functional-programming scala currying implicit-conversion

如果我有一个功能:

f : A => B => C
Run Code Online (Sandbox Code Playgroud)

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

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

Apo*_*isp 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)
Run Code Online (Sandbox Code Playgroud)

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

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)
Run Code Online (Sandbox Code Playgroud)

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

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)
Run Code Online (Sandbox Code Playgroud)

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

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


Rex*_*err 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?
Run Code Online (Sandbox Code Playgroud)

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

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

  • 请注意,您将无法使用参数"A => B => C"和"D => C"重载函数,因为它们具有相同的擦除.所以问题不会在实践中以这种方式出现. (4认同)