例如在Elm基础文档中:
(/) : Float -> Float -> Float
这就是说/
是一个函数,该函数接受一个浮点数,另一个浮点数并返回一个浮点数。
为什么会这样:
(/) : (Float, Float) -> Float
例如,这似乎更直观。
这是否有特殊原因?这也是在Haskel中注释类型的方式。
https://package.elm-lang.org/packages/elm/core/latest/Basics
编辑:已经回答了,但是我也在Elm的文档中找到了这个: https://guide.elm-lang.org/appendix/function_types.html
答案 0 :(得分:9)
从技术上讲,榆木的功能不止一个。类型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)
,其中arg1
和arg2
是浮点数,或f tup
,其中tup
是两个浮点数的元组。
答案 1 :(得分:5)
在函数式编程中,使用返回其他函数的版本更容易,因此当您看到(/) : Float -> Float -> Float
时,意味着可以传递一个参数并返回函数Float -> Float
。因此,有效的结果是没有区别的(假设您同时传递了两个参数)。
这种从元组版本(未咖喱的版本)到功能版本(咖喱的版本)的技术被称为currying,并且被广泛使用,并且在实践后将变得直观。我不熟悉elm
,但是在Haskell中,您可以轻松地从咖喱版本返回:
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