代码之家  ›  专栏  ›  技术社区  ›  oxbow_lakes

为什么咖喱和未咖喱不隐含在scala中?

  •  13
  • oxbow_lakes  · 技术社区  · 14 年前

    如果我有一个函数:

    f : A => B => C
    

    我可以定义隐式转换,以便在函数 (A, B) => C 是意料之中的事。这也指向另一个方向。

    为什么这些转换没有 隐性的 (或隐式可用)?我想是的 坏事情可能发生 为了一些不好的东西。这是什么价值?

    2 回复  |  直到 14 年前
        1
  •  12
  •   Apocalisp    14 年前

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

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

    让我们知道它在实践中是如何运作的。您可能需要功能3、功能4等的等效项。

        2
  •  8
  •   Rex Kerr    14 年前

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

    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?
    

    强输入的一部分好处是当你做了一些愚蠢的事情时警告你。努力工作会降低收益。在这里,如果转换是自动完成的,您可能不会调用您想要调用的方法。

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