例如:
f :: (b -> c) -> (a -> b) -> c
g h
函数f将两个函数(让我们称之为g和h)作为输入参数,并返回一个类型为c的值
第一个论点:(a -> b)
第二个论点:(b -> c)
返回:类型c
为了使此函数定义为真,类型必须排列,如下所示:(a -> b) -> (b -> c)
< = equivalent to => a -> c
并且唯一的方法是将第二个参数用作第一个参数的输入,如g(h(x)),其中x是a类型,对于Haskell中的所有函数都是如此?换一种说法 是正确的参数总是被定义为其左参数的输入?这是Haskell中所有组合函数的一般情况吗? 如果是这样,我应该总是从右到左而不是从左到右阅读和解释函数参数?
OBS: 这个问题与以下问题不同: Why does the dot compose from right to left in haskell 因为我的问题对于所有函数都更通用,我也已经知道由其他函数组成的函数称为函数组合,我知道点函数等。
答案 0 :(得分:6)
我认为你可能会把事情搞得一团糟。在您的示例中,复制如下:
f :: (b -> c) -> (a -> b) -> c
此处f
是higher order function,这意味着它可以将其他函数作为参数。事实上,它的第一个参数是(b -> c)
类型的函数。它的第二个参数是(a -> b)
类型的函数。
函数的参数根本不必相互关联。在你的情况下,这只是一个巧合。我们可以很容易地完成这样的事情:
g :: (Int -> Double) -> (Char -> Bool) -> String
g func1 func2 = "three"
另一件需要注意的事情是Haskell中的所有函数都是curried。回想一下像C这样的语言:
char foo (int a, double b) { ... }
该函数需要(int, double)
并返回char
。我们甚至可以像这样写出它的类型签名:
(int, double) -> char
在Haskell中,我们不要求所有参数立即输入,并表示为:
int -> double -> char
为什么世界上你想要这个?请考虑以下情形:
add :: Int -> Int -> Int
add a b = a + b
检查出来:
addFive :: Int -> Int
addFive = add 5
应用 less 参数而不是函数的参数需要允许您创建稍微“自定义”的新函数。很酷,对吧? :)