2011-12-18 37 views
3

我需要在SML中編寫一個非常簡單的函數。它應檢查值'elem'是否大於列表'L'中字段'f1'的任何值。列表'L'包含3個字段 - 'f1','f2','f3'。如果語句'elem> f1'對於列表'L'的任何成員都是真的,函數應該返回1。否則,函數應返回0.例如:WHILE循環爲LIST

L = 
f1 f2 f3 
1 4 6 
2 1 2 
3 4 8 
8 5 9 

elem = 3 

fun check(L: myList, elem: int): int = 
let 
    val counter = ref 0 
    val counter_end = length L 
in 
     while (!counter <= counter_end) do 
      let val f1 = List.nth(L,counter) 
      in 
       if elem > f1 then 1 else 0 
      end 
      counter := !counter + 1 
end 

我不知道如何從列表'L'中獲取字段'f1'。任何想法高度讚賞。

+2

您使用while循環的任何特定原因?這在SML中通常是一個糟糕的主意。 – jalf 2011-12-18 21:35:19

+0

嗯,我只是SML的新手,所以我沒有其他想法來解決我的問題。但是,如果您知道其他解決方案,請在此處描述。謝謝。 – 2011-12-18 21:44:15

+0

該函數應該返回什麼?如果沒有名單上的成員有'elem> f1',會發生什麼? – jalf 2011-12-18 21:53:33

回答

2

在SML(和一般的函數式語言),您通常要依靠遞歸而不是命令式結構類似的循環。

我在SML有點生疏,但這裏的定義函數

fun check elem [] = 0 
    | check elem ((f1,f2,f3)::tl) = if elem > f1 then 1 else check elem tl; 

然後它可以這樣調用一個方法:

(* define a list to scan *) 
val L = [(1,4,6),(2,1,2),(3,4,8),(8,5,9)]; 
(* call the function on our list *) 
check 3 L; 

功能是遞歸定義,使用模式匹配:第一行說如果在空列表上調用該函數,結果爲零。 第二行說如果它在列表上被調用,其中第一個元素是元組(f1,f2,f3),則結果爲1,如果是elem > f1,否則它是在列表尾部遞歸調用函數的結果

另請注意,我省略了類型說明符。你很少需要它們,因爲語言會自動推斷出這些類型。編譯器已經知道哪些類型可以安全地使用你寫的代碼,那麼爲什麼還要告訴它你認爲參數將會是什麼類型?

+0

謝謝,我明白了。 – 2011-12-18 22:32:30

2

使用遞歸函數而不是使用循環。 (使用布爾返回而不是整數可能更有意義。)

提取字段的最簡單方法是通過參數列表中的模式匹配。假設你的三個字段是一個元組,像這樣:

fun check((f1,f2,f3)::L: myList, elem: int)