Haskell函数和柯里化
我正在尝试学习 Haskell 并开始阅读有关它的书。看起来很有趣,即使一开始很难理解,也想继续我的旅程。我有这段代码,我想了解它为什么起作用。
names = [("Ian", "Curtis"), ("Bernard", "Summer"), ("Peter", "Hook"), ("Stephen", "Morris")]
compareLastNames name1 name2
| lastName1 > lastName2 = GT
| lastName1 < lastName2 = LT
| otherwise = EQ
where
lastName1 = snd name1
lastName2 = snd name2
main = do
print (sortBy compareLastNames names)
我不明白的是compareLastNames需要两个参数,但即使我将元组列表传递给它,它也能正常工作。我知道 haskell curries 函数,但它是如何工作的。函数怎么可能接受元组列表而不抛出错误?
回答
柯里化与此无关。
在(sortBy compareLastNames names)您调用sortBy传递两个参数compareLastNames的函数时:(一个函数)和names(一个对列表)。这不会compareLastNames以任何方式直接调用函数;特别是,这个函数不是names作为参数传递的——正如你意识到的那样,这将是一个类型错误。
该函数compareLastNames仅在 的定义内调用sortBy,这将为它提供正确类型的参数(两对)。
为了强调这一点,请考虑:
foo :: (String -> Int) -> Int -> Int
foo g x = x + g "abcde"
myG :: String -> Int
myG = length
test :: Int
test = foo myG 42
这里我们不调用myGwith 42,它不是一个字符串。相反,我们评估test为:
test
= foo myG 42
= 42 + myG "abcde"
= 42 + 5
= 49
这里要理解的关键点是我们myG作为函数值传递,而不是将其应用于其他值所获得的结果。传递 unappliedmyG允许foo为 选择参数myG。