如果我有一个功能:
f : A => B => C
我可以定义一个隐式转换,以便可以在需要函数(A, B) => C
的地方使用它。这也朝着另一个方向发展。
为什么这些转换不是隐式的(或隐式可用的)?我假设坏事可能会因某些价值的坏事而发生。这是什么价值?
如果我有一个功能:
f : A => B => C
我可以定义一个隐式转换,以便可以在需要函数(A, B) => C
的地方使用它。这也朝着另一个方向发展。
为什么这些转换不是隐式的(或隐式可用的)?我假设坏事可能会因某些价值的坏事而发生。这是什么价值?
我不认为会有什么不好的事情发生。转换是完全明确的。最坏的情况是,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 等的等效项。
您不希望它们在默认情况下隐式可用(始终打开),因为当您使用一堆类似类型的参数重载时,类型系统将无法帮助您:
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?
强类型的部分优势是当你做了一些愚蠢的事情时会警告你。过分努力让事情顺利进行会降低收益。在这里,如果转换是自动完成的,您可能不会调用您想要调用的方法。
根据要求隐含地提供它们很好,但如果你需要的话,自己做并不难。这是我很少使用的东西;我不会把它放在我想在图书馆里的前十名甚至前一百名的东西中(部分原因是我可能更喜欢自动转换为元组而不是自动柯里化/非柯里化)。