为什么 (b) of (a -> (b -> c)) 不是函数定义中的第一个参数,而是类型签名中的第二个参数?

Aka*_*ari 5 haskell currying type-signature

如果函数首先采用第一个参数,因为函数应用程序是左关联的,例如:

drop 2 [1,2,3,4]
Run Code Online (Sandbox Code Playgroud)

结果:[3,4]

相当于

(drop 2) [1,2,3,4]
Run Code Online (Sandbox Code Playgroud)

相同的结果:[3,4]

这里我的问题是,如果类型签名是右关联的,这意味着,首先评估右侧的内容,在这种情况下,它将如下所示,因为第一个参数首先由函数获取:

drop :: [1,2,3,4] -> (2 -> [3,4])
Run Code Online (Sandbox Code Playgroud)

不应该是下面这个样子吧?

drop :: Int -> ([a] -> [a])
drop :: 2 -> ([1,2,3,4] -> [3,4])
Run Code Online (Sandbox Code Playgroud)

那么,为什么在函数的类型签名中首先采用第二个参数而不是第一个参数呢?

另外,如果第二个参数先于第一个参数求值,那么为什么下面的用法无效?

(drop [1,2,3,4]) 2
Run Code Online (Sandbox Code Playgroud)

lef*_*out 10

编写诸如drop :: [1,2,3,4] -> (2 -> [3,4])或2 -> ([1,2,3,4] -> [3,4])\xe2\x80\x93 之类的东西是没有意义的,因为你在那里混合了类型级别和值级别的符号。相反,您应该做的是查看子表达式的局部类型:

\n
drop                  2    [1,2,3,4]\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\xac\xe2\x94\x98                  \xe2\x94\x8a    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\xac\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n\xe2\x94\x8c\xe2\x94\x80\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90 \xe2\x94\x8c\xe2\x94\x80\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x90  \xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90\n\xe2\x94\x82Int->[Int]->[Int]\xe2\x94\x82 \xe2\x94\x82Int\xe2\x94\x82  \xe2\x94\x82[Int]\xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98  \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n
Run Code Online (Sandbox Code Playgroud)\n

添加隐含的括号

\n
(drop                   2)    [1,2,3,4]\n \xe2\x94\x94\xe2\x94\xac\xe2\x94\x80\xe2\x94\x98                   \xe2\x94\x8a     \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\xac\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n\xe2\x94\x8c\xe2\x94\x80\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90 \xe2\x94\x8c\xe2\x94\x80\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x90   \xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90\n\xe2\x94\x82Int->([Int]->[Int])\xe2\x94\x82 \xe2\x94\x82Int\xe2\x94\x82   \xe2\x94\x82[Int]\xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n
Run Code Online (Sandbox Code Playgroud)\n

现在,子表达式drop 2意味着您将参数应用2为 function 的第一个参数drop,即作为Int其签名中的 the 。对于整个drop 2表达式,这个论点因此消失了:

\n
(           drop           2   )  [1,2,3,4]\n\xe2\x94\x8a  \xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90 \xe2\x94\x8c\xe2\x94\x80\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x90 \xe2\x94\x8a  \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\xac\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n\xe2\x94\x8a  \xe2\x94\x82Int->([Int]->[Int])\xe2\x94\x82 \xe2\x94\x82Int\xe2\x94\x82 \xe2\x94\x8a     \xe2\x94\x8a\n\xe2\x94\x8a  \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98 \xe2\x94\x8a     \xe2\x94\x8a\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xac\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98  \xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90\n        \xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90            \xe2\x94\x82[Int]\xe2\x94\x82\n        \xe2\x94\x82[Int]->[Int]\xe2\x94\x82            \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n        \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n
Run Code Online (Sandbox Code Playgroud)\n

这类似于将单参数函数应用于length :: [Bool] -> Int单个参数[False,True] :: [Bool]以获得结果length [False,True] \xe2\x89\xa1 (2::Int)。事实上,drop结果具有类型([Int]->[Int])而不是像 \xe2\x80\x9catomic\xe2\x80\x9d 这样的东西,Int在这个阶段是无关紧要的。

\n

然后在外层,您将 type 的函数应用于[Int]->[Int]type 的参数[Int],这是完全合理的。整个事情就只有结果类型[Int]。

\n
( (           drop           2   )  [1,2,3,4] )\n\xe2\x94\x8a \xe2\x94\x8a  \xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90 \xe2\x94\x8c\xe2\x94\x80\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x90 \xe2\x94\x8a  \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\xac\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98 \xe2\x94\x8a\n\xe2\x94\x8a \xe2\x94\x8a  \xe2\x94\x82Int->([Int]->[Int])\xe2\x94\x82 \xe2\x94\x82Int\xe2\x94\x82 \xe2\x94\x8a     \xe2\x94\x8a      \xe2\x94\x8a\n\xe2\x94\x8a \xe2\x94\x8a  \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98 \xe2\x94\x8a     \xe2\x94\x8a      \xe2\x94\x8a\n\xe2\x94\x8a \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xac\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98     \xe2\x94\x8a      \xe2\x94\x8a\n\xe2\x94\x8a         \xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90            \xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90   \xe2\x94\x8a\n\xe2\x94\x8a         \xe2\x94\x82[Int]->[Int]\xe2\x94\x82            \xe2\x94\x82[Int]\xe2\x94\x82   \xe2\x94\x8a\n\xe2\x94\x8a         \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98            \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98   \xe2\x94\x8a\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xac\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n                      \xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90\n                      \xe2\x94\x82[Int]\xe2\x94\x82\n                      \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n
Run Code Online (Sandbox Code Playgroud)\n


Wil*_*sem 6

我认为您误解了右结合的含义。这确实意味着:

drop :: Int -> [a] -> [a]
Run Code Online (Sandbox Code Playgroud)

相当于:

drop :: Int -> ([a] -> [a])
Run Code Online (Sandbox Code Playgroud)

因此,这意味着drop是一个采用 类型参数Int,然后返回类型函数[a] -> [a]的函数。

但函数应用本身是左关联的。的确:

drop 2 [1,2,3,4]
Run Code Online (Sandbox Code Playgroud)

是缩写:

(drop 2) [1,2,3,4]
Run Code Online (Sandbox Code Playgroud)

因此,这里drop 2将返回一个类型的函数[a] -> [a],该函数将删除列表的前两项。然后我们应用[1,2,3,4]该函数,从而获得[3,4]。