为什么我们用箭头显示多个参数并用箭头显示 return 类型?
Why do we show multiple arguments with arrows and the return type with an arrow?
例如在 Elm 基础文档中:
(/) : Float -> Float -> Float
这是说 /
是一个函数,它接受一个浮点数,另一个浮点数和 returns 一个浮点数。
为什么不是这样:
(/) : (Float, Float) -> Float
举个例子,好像比较直观
这有什么特殊原因吗?这也是在 Haskel 中注释类型的方式。
https://package.elm-lang.org/packages/elm/core/latest/Basics
编辑:这已经得到回答,但我也在 Elm 的文档中找到了这个:
https://guide.elm-lang.org/appendix/function_types.html
在函数式编程中,使用 returns 其他函数的版本更容易,所以当您看到 (/) : Float -> Float -> Float
时,这意味着您可以传递一个参数并返回函数 Float -> Float
。因此实际上结果没有区别(假设您传递了两个参数)。
这种从元组版本(未柯里化)到函数式版本(柯里化)的技术称为柯里化,被广泛使用,经过实践会变得直观。我不熟悉 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
仅应用于一个参数,您将得到一个可以重复使用的函数。查看 wiki 的 Haskell wiki for more details. In contrary with function which expect tuple the re-usability will be limited. Check also the Partial application 部分以了解其重要性。
add2 :: Integer -> Integer -> Integer
add2 a b = a + b
add5 :: Integer -> Integer
add5 b = add2 5 b -- add2 is re-used
从技术上讲,Elm 没有多于一个参数的函数。 Float -> Float -> Float
类型(与 Float -> (Float -> Float)
相同,因为 ->
是右结合的)表示一个接受 Float
的函数和 returns 另一个接受的函数另一个浮动。然后像 (/) 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)
其中 arg1
和 arg2
是浮点数或 f tup
其中 tup
是两个浮点数的元组。
例如在 Elm 基础文档中:
(/) : Float -> Float -> Float
这是说 /
是一个函数,它接受一个浮点数,另一个浮点数和 returns 一个浮点数。
为什么不是这样:
(/) : (Float, Float) -> Float
举个例子,好像比较直观
这有什么特殊原因吗?这也是在 Haskel 中注释类型的方式。
https://package.elm-lang.org/packages/elm/core/latest/Basics
编辑:这已经得到回答,但我也在 Elm 的文档中找到了这个: https://guide.elm-lang.org/appendix/function_types.html
在函数式编程中,使用 returns 其他函数的版本更容易,所以当您看到 (/) : Float -> Float -> Float
时,这意味着您可以传递一个参数并返回函数 Float -> Float
。因此实际上结果没有区别(假设您传递了两个参数)。
这种从元组版本(未柯里化)到函数式版本(柯里化)的技术称为柯里化,被广泛使用,经过实践会变得直观。我不熟悉 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
仅应用于一个参数,您将得到一个可以重复使用的函数。查看 wiki 的 Haskell wiki for more details. In contrary with function which expect tuple the re-usability will be limited. Check also the Partial application 部分以了解其重要性。
add2 :: Integer -> Integer -> Integer
add2 a b = a + b
add5 :: Integer -> Integer
add5 b = add2 5 b -- add2 is re-used
从技术上讲,Elm 没有多于一个参数的函数。 Float -> Float -> Float
类型(与 Float -> (Float -> Float)
相同,因为 ->
是右结合的)表示一个接受 Float
的函数和 returns 另一个接受的函数另一个浮动。然后像 (/) 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)
其中 arg1
和 arg2
是浮点数或 f tup
其中 tup
是两个浮点数的元组。