嗨我有一個簡單的haskell定義的查詢。我有一個定義,但我不完全理解它。Haskell初學者查詢
該函數接受函數和項目列表並返回通過應用該函數形成的列表。
applyAll = \fs -> \x -> map(\n -> n x) fs
有人能解釋什麼是N不需要,爲什麼地圖功能之外FS?
嗨我有一個簡單的haskell定義的查詢。我有一個定義,但我不完全理解它。Haskell初學者查詢
該函數接受函數和項目列表並返回通過應用該函數形成的列表。
applyAll = \fs -> \x -> map(\n -> n x) fs
有人能解釋什麼是N不需要,爲什麼地圖功能之外FS?
間距誤導你。它看起來像map(\n -> n x)
是一個函數調用,但這裏的括號是用於分組,而不是函數調用。 map
需要兩個參數;完整調用map (\n -> n x) fs
,其中(\n -> n x)
是第一個參數(lambda表達式),fs
是第二個參數。
lambda \n -> n x
是一個函數,它將函數作爲參數並返回將該函數應用到x
的結果。 n
是這裏的論據。 \n -> n x
的類型是(a -> b) -> b
(其中a
是x
的類型)。如果您已經瞭解了部分,則lambda等同於部分($ x)
。如果你還沒有,那就忽略最後一句話。
這裏有一個簡單的函數定義:
f x = 2*x + 1
這將創建一個新的功能f
,這需要一個參數。您可以稍後使用它:
main = print (f 3)
...將打印7.有時,可以方便地定義一個函數而不給它一個名稱。其語法是\{- argument -} -> {- function body -}
;例如,我們可以做的f
匿名版本,這樣上面:現在
main = print ((\x -> 2*x + 1) 3)
,你的applyAll
定義,只是做了幾次。我們可以明確命名一切where
條款,如果我們想:
applyAll = outerMost where
outerMost fs = mapApply where
mapApply x = map applyToX fs where
applyToX n = n x
...雖然我想你會同意,額外的冗長並沒有讓事情變得更加清晰!而更自然的(但不機械)翻譯從匿名函數遠是這樣的:
applyAll fs x = map applyToX fs where
applyToX n = n x
,現在希望這可以非常近看像英語:到fs
應用所有的功能爲單個值x
,我們映射「在所有函數列表上應用單個函數(我們暫時命名爲n
)的函數爲值x
」。
函數定義:
applyAll = \fs -> \x -> map(\n -> n x) fs
是一樣的:
applyAll fs x = map(\n -> n x) fs
現在你可能會問,「什麼是那些->
正在做那裏,如果他們只是參數我的功能applyAll
。Haskell沒有多參數函數的概念。你看到的作爲一個函數的多個參數僅僅是連接在一起的多個函數各自與單個參數。在applyAll
的情況下,它只是兩個函數鏈接在一起:
(applyAll fs) -> x = map (\n -> n x) fs
applyAll fs
是鏈接到標識爲x
產生由map
返回值的列表,另一種說法一個功能。
我可以在ghci中嘗試了這一點:
Prelude> :t applyAll
applyAll :: [t -> b] -> t -> [b]
Prelude> :t applyAll xs
<interactive>:1:10: Not in scope: `xs'
Prelude> let xs = [1..5]
-- hah, BOOM! I told you haskell's strongly typed...
Prelude> :t applyAll xs
<interactive>:1:10:
Couldn't match expected type `t0 -> b0' with actual type `Integer'
Expected type: [t0 -> b0]
Actual type: [Integer]
In the first argument of `applyAll', namely `xs'
In the expression: applyAll xs
Prelude> let xs = [(1 +), (2 +), (3 *), (4 /)]
Prelude> :t xs
xs :: [Double -> Double]
Prelude> :t applyAll xs
applyAll xs :: Double -> [Double]
Prelude> :t applyAll
applyAll :: [t -> b] -> t -> [b]
Prelude> :t applyAll xs 3
applyAll xs 3 :: [Double]
Prelude> applyAll xs 3
[4.0,5.0,9.0,1.3333333333333333]
什麼的map
類型?
map :: (a -> b) -> [a] -> [b]
這告訴我,map
需要一個功能 - 我們稱之爲f
和值的列表返回值的另一個列表。函數f
是一個類型爲a
的值返回b
類型的值。因此,map
繼續將f
應用於列表[a]
中的每個值,以返回填充了類型爲b
的值的另一個列表。
在您的applyAll
中,函數f
是\n -> n x
。這是一個lambda表達式(您可以稱之爲匿名函數),其值爲n
,並將x
應用於該值。對於類型定義中由[a]
標識的輸入列表中的每個項目都會繼續執行,直到在類型定義中產生另一個由[b]
標識的列表。