为什么咖喱和不咖喱在scala中不是隐含的

为什么咖喱和不咖喱在scala中不是隐含的,scala,functional-programming,currying,implicit-conversion,Scala,Functional Programming,Currying,Implicit Conversion,如果我有一个函数: f : A => B => C 我可以定义隐式转换,这样就可以在需要函数(a,B)=>C时使用。这也是另一个方向 为什么这些转换不是隐式的(或隐式的)?我假设坏事情可能发生,因为坏事情的某些价值。这有什么价值?我不认为会发生什么坏事。转换是完全明确的。最坏的情况是,Scala无法确定隐式转换是否适用 implicit def curryImplicitly[A,B,C](f: (A, B) => C) = (a: A) => (b: B) =&g

如果我有一个函数:

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?
当你做了愚蠢的事情时,强力打字的一部分好处是警告你。太过努力地使事情运转会降低效益。在这里,如果转换是自动完成的,您可能不会调用您想要调用的方法


根据请求隐式地提供它们是很好的,但是如果您需要的话,您自己做也不难。这是我很少使用的东西;我不会把它放在我最喜欢的库中的前十名,甚至可能是前一百名(部分原因是我可能更喜欢自动转换为元组,而不是自动咖喱/不咖喱)。

我在2.8中没有使用过它,但我在2.7.X的黑暗时期尝试过,它往往会导致编译器崩溃,在类型推断器iirc中。在这方面,情况已经有了相当大的改进,所以现在可能一切都好了……是的,如果你试图让它推断出更高类型的类型,编译器仍然很容易崩溃,但这比2.7有了巨大的改进。我在2.8中尝试了这些简单的情况,注意,您将无法使用参数
a=>B=>C
D=>C
重载函数,因为它们具有相同的擦除。因此,在实践中,问题不会以这种方式出现。啊,你是对的。如果您使用不同的方法名,但方法名有误,则使用类型签名作为双重检查仍然很有帮助。