部分申请

让我们澄清初学者可能会犯的一些误解。

你可能遇到过以下功能:

max :: (Ord a) => a -> a -> a  
max m n  
  | m >= n = m  
  | otherwise = n  

初学者通常将 max :: (Ord a) => a -> a -> a 视为具有 a 类型的两个参数(值)的函数,并返回 a 类型的值。然而,真正发生的是,max 正在采用 a 类型的一个参数返回 a -> a 类型的函数。然后该函数接受 a 类型的参数并返回 a 类型的最终值。

实际上,max 可以写成 max :: (Ord a) => a -> (a -> a)

考虑 max 的类型签名:

Prelude> :t max  
max::Ord a => a -> a -> a  

Prelude> :t (max 75)  
(max 75) :: (Num a, Ord a) => a -> a  

Prelude> :t (max "Fury Road")  
(max "Fury Road") :: [Char] -> [Char]  

Prelude> :t (max "Fury Road" "Furiosa")  
(max "Fury Road" "Furiosa") :: [Char]  

max 75max "Fury Road" 可能看起来不像功能,但实际上,它们是。

混淆源于这样一个事实:在数学和许多其他常见的编程语言中,我们被允许具有多个参数的函数。但是,在 Haskell 中,**函数只能接受一个参数,**并且它们可以返回诸如 a 之类的值,或者诸如 a -> a 之类的函数。