为什么 scala 中柯里化和非柯里化不隐含

发布于 2024-09-14 12:31:42 字数 228 浏览 6 评论 0原文

如果我有一个函数:

f : A => B => C

我可以定义一个隐式转换,以便可以在函数 (A, B) => 的地方使用它。 C 是预期的。这也朝着另一个方向发展。

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

If I have a function:

f : A => B => C

I can define an implicit conversion such that this can be used where a function (A, B) => C is expected. This goes in the other direction also.

Why are these conversions not implicit (or available implicitly)? I am assuming that bad things could happen for some value of bad things. What value is this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

小姐丶请自重 2024-09-21 12:31:42

我认为不会发生什么不好的事情。转换是完全明确的。最坏的情况是,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 等的等效项。

I don't think anything bad will happen. The conversion is completely unambiguous. Worst case, Scala will not be able to figure out that the implicit conversion applies.

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)

Then again, these would also be helpful.

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)

But those aren't transitive, so you need these:

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)

But now the conversion is ambiguous. So it's not all roses.

Let's know how it works out in practise. You might need equivalents for Function3, Function4, etc.

美人骨 2024-09-21 12:31:42

您不希望它们在默认情况下隐式可用(始终打开),因为当您重载了一堆类似类型的参数时,类型系统将无法帮助您:

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?

强类型的部分优点是在您重载时向您发出警告做了一些愚蠢的事情。过于努力地让事情顺利进行会降低收益。在这里,如果转换是自动完成的,您可能不会调用您想要调用的方法。

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

You don't want them implicitly available by default (always-on) because then the type system has trouble helping you out when you have overloaded with arguments of a bunch of similar types:

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?

Part of the advantage of strong typing is warning you when you've done something foolish. Trying too hard to make things work reduces the benefits. Here, if the conversions were done automatically, you might not call the method you meant to call.

Having them available implicitly upon request is fine, but it's not that hard to do it yourself if you need it. This is something that I would use quite rarely; I wouldn't put it in my top ten or probably even top hundred things that I'd like in the library (in part because I might prefer the automatic conversion to a tuple instead of the automatic currying/uncurrying).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文