假設我們有這兩個功能
f1 :: Int -> [Int] -> Int -> [Int]
f1 _ [] _ = []
f1 x (h:t) y = (x * h y):(f1 x t y)
f2 :: [Int] -> Int
f2 (h:t) = h
為什么(f2 . f1 1 [1..10]) 1有效,但(f2 . f1 1) [1..10] 1無效?
uj5u.com熱心網友回復:
Haskell 中的所有函式都只接受一個引數并回傳一個值。引數和/或回傳型別可以是另一個函式。
f1有一個引數型別Int和一個回傳型別[Int] -> Int -> [Int]。的正確關聯性(->)意味著我們不必明確地將其寫為
f1 :: Int -> ([Int] -> (Int -> [Int]))
但可以改為洗掉括號。
(是的,(->)是一個運算子。你可以:k在 GHCi 中使用來查看那種,但不幸的是,你得到的比我們在這里要解釋的要復雜得多:
> :k (->)
(->) :: TYPE q -> TYPE r -> *
不要擔心什么TYPE q和TYPE r立場。可以說它(->)接受兩種型別并回傳一個新型別,我們可以假設一個更簡單的型別
(->) :: * -> * -> *
那種*是普通型別的那種,現在寫得比較頻繁Type。)
為了組合兩個函式,一個函式的回傳型別必須與另一個函式的引數型別相匹配。我們可以從(.)自身的型別看出這一點:
(.) :: (b -> c) -> (a -> b) -> a -> c
^ ^
f1和不是這種情況f2:
-- vvvvvvvvvvvvvvvvvvvvv
f1 :: Int -> ([Int] -> Int -> [Int])
f2 :: [Int] -> Int
-- ^^^^^
-- [Int] -> Int -> [Int] and [Int] are different types
也沒有f1 1和f2
-- vvvvvvvvvvvv
f1 1 :: [Int] -> (Int -> [Int])
f2 :: [Int] -> Int
-- ^^^^^
-- Int -> [Int] and [Int] are different types
但它是真實的f1 1 [1..10]and f2:
-- vvvvv
f1 1 [1..10] :: Int -> [Int]
f2 :: [Int] -> Int
-- ^^^^^
-- [Int] and [Int] are the same type
While(->)是右關聯的,函式應用是左關聯的,這就是我們可以寫的原因
((f1 1) [1..10]) 1
asf1 1 [1..10] 1相反,導致f1as 出現 3 個引數,而不是包含 3 個單獨函式呼叫的運算式。如果您使用let運算式顯式命名每個中間函式,您可以更清楚地看到這三個呼叫:
let t1 = f1 1
t2 = t1 [1..10]
t3 = t2 1
in t3
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/532460.html
標籤:哈斯克尔
上一篇:IO物件問題Haskell
