2013-12-12 71 views
3

我具備的功能:SML地圖功能

map(map(fn x =>[x])) [[],[1],[2,3,4]]; 

主要生產:

val it = [[],[[1]],[[2],[3],[4]]] 

我不明白這個功能是如何工作的。每個映射函數都不需要函數和列表嗎?似乎沒有足夠的參數來實際執行。

如果我運行:

map(fn x =>[x]) [[],[1],[2,3,4]]; 

我得到:

val it = [[[]], [[1]], [[2,3,4]]]; 

這讓我更有意義,因爲它需要在列表中的每個元素,並把它封裝在另一個列表。但是當我在其上放置另一個地圖時,它會改變輸出。任何人都可以向我解釋這個嗎?謝謝!

回答

9

你說:

我不明白這個功能是如何工作的。每個映射函數都不需要函數和列表嗎?

那麼,請記住,在標準ML(以及一般的所有應用語言)中,除了「1」之外,不存在「n參數的函數」這樣的事情。中,多於一個參數的函數可以是兩種方式模擬

  1. 作爲該是一個元組或記錄的單個參數的函數。原始的預期參數可以通過元組或記錄的投影在函數體中恢復。

  2. 作爲返回其餘參數的函數的第一個參數的函數。

考慮到這一點,我們檢查map的類型在REPL:

> map; 
val it = fn: ('a -> 'b) -> 'a list -> 'b list 

(我用的保利/ ML,而不是SML/NJ,但格式問題放在一邊,輸出應該是)

沒有元組,沒有記錄。 map顯然採用第二種方法來模擬兩個參數的函數:它採用'a -> 'b類型的函數並返回另一個函數的類型爲'a list -> 'b list

現在,這裏是這個問題:對於任何函數foomap foo也是一個函數!由於map可以帶任何函數作爲參數,map foo本身是一個map完全合法的參數。這意味着map (map foo) typechecks任何功能foo。特別是,如果val foo = fn x => [x]是這樣。


你說:

似乎沒有足夠的論據,這實際執行。

如果它檢測到,它會運行。


你說:

如果我運行

map (fn x => [x]) [[], [1], [2,3,4]] 

我得到

val it = [[[]], [[1]], [[2,3,4]]]; 

這讓我更有意義,因爲它需要每一個元素列表並將其封裝在另一個列表中。但是當我在其上放置另一個地圖時,它會改變輸出。

讓我們重構你的代碼一點點,但不改變其含義:

let 
    val foo = fn x => [x] 
    val bar = map foo 
    val baz = map bar 
in 
    baz [[], [1], [2,3,4]] 
end 

現在我們可以分析功能(foobarbaz)是每個確實給它的參數:

  1. foo採用單個元素x並將其包裝在列表數據構造函數中。
  2. bar獲取元素列表,將每個元素封裝在列表數據構造函數中,並返回一個列表以及生成的封裝元素(列表列表)。
  3. baz獲取(子)列表元素列表,將bar應用於每個子列表,並返回一個包含結果的列表。

手動執行所有這些操作來說服您自己確信結果[[], [[1]], [[2], [3], [4]]]的確是正確的。

0
map ; 
val it = fn : ('a -> 'b) -> 'a list -> 'b list 

因此map需要一個函數,它再次列表並給出一個列表。

因此,與功能

-fun f x = x+1 ; 
val f = fn : int -> int 
-map f ; 
val it = fn : int list -> int list 
現在

it定義地圖是該類型的函數,該函數列表,並返回一個列表

- it [1,2] ; 
val it = [2,3] : int list 

我認爲地圖功能明確