【问题标题】:Why do we show multiple arguments with arrows and the return type with an arrow?为什么我们用箭头显示多个参数,用箭头显示返回类型?
【发布时间】:2020-01-30 20:17:56
【问题描述】:

例如在 Elm 基础文档中:

(/) : Float -> Float -> Float

这就是说/ 是一个函数,它接受一个浮点数,另一个浮点数并返回一个浮点数。

为什么不这样:

(/) : (Float, Float) -> Float

例如,这似乎更直观。

这有什么特殊原因吗?这也是 Haskel 中类型注解的方式。

https://package.elm-lang.org/packages/elm/core/latest/Basics

编辑:这已经得到回答,但我也在 E​​lm 的文档中找到了这个: https://guide.elm-lang.org/appendix/function_types.html

【问题讨论】:

    标签: functional-programming elm


    【解决方案1】:

    从技术上讲,Elm 没有多个参数的函数。 Float -> Float -> Float 类型(与 Float -> (Float -> Float) 相同,因为 -> 是右关联的)表示一个接受 Float 并返回另一个接受另一个浮点数的函数的函数。然后像(/) a b 这样的调用(与((/) a) b 相同,因为函数应用程序是左关联的)首先将函数(/) 应用于a,然后将生成的函数应用于b

    请注意,您也可以只将/ 应用于单个参数,而不立即将结果应用于第二个参数:例如inv = (/) 1 将定义一个inv 函数,其作用与inv x = 1 / x 相同。

    (Float, Float) -> Float 是一个函数类型,它接受一个包含两个浮点数的元组。您可以像这样定义具有该类型的函数:

    f: (Float, Float) -> Float
    f (x,y) = ...
    

    然后您可以将其称为f (arg1, arg2),其中arg1arg2 是浮点数或f tup,其中tup 是两个浮点数的元组。

    【讨论】:

      【解决方案2】:

      在函数式编程中,使用返回其他函数的版本更容易,因此当您看到(/) : Float -> Float -> Float 时,这意味着您可以传递一个参数并返回函数Float -> Float。如此有效,结果没有区别(假设您同时传递了两个参数)。

      这种从元组版本(uncurried)到函数版本(curried)的技术称为currying,被广泛使用,实践后会变得直观。我不熟悉elm,但在 Haskell 中,您可以轻松地从 curried 版本返回:

      f :: a -> (b -> c)     -- (which can also be written as    f :: a -> b -> c )
      g :: (a, b) -> c
      
      f = curry g -- transform argument from tuple to functions
      g = uncurry f -- transform function arguments to tuple
      

      因此,如果您仅将函数 f 应用于一个参数,您将返回一个可以重复使用的函数。查看Haskell wiki 了解更多详情。与期望元组的函数相反,可重用性将受到限制。另请查看 wiki 的 Partial application 部分,了解它为何如此重要。

      add2 :: Integer -> Integer -> Integer
      add2 a b = a + b
      
      add5 :: Integer -> Integer
      add5 b = add2 5 b -- add2 is re-used
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-01-18
        • 2014-12-26
        • 2012-06-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-10
        相关资源
        最近更新 更多