2012-03-25 59 views
0

我試圖在SML一個函數,一個列表和一個int並返回小於INT int * int list -> int list我寫了下面的代碼的所有元素的列表:低於標準ML作用

- fun less (e, L) = 
= map (fn a => if a < e then a else []) L; 

還用下面的代碼是不工作也:

- fun less (e, L) = 
= map (fn a => if a < e then a) L; 

和錯誤即時得到的是:

stdIn:22.15-22.38 Error: types of if branches do not agree [overload] 
    then branch: 'Z 
    else branch: 'Y list 
    in expression: 
    if a < e then a else nil 

我認爲問題與其他部分有關,但我不知道該如何工作,有人有什麼建議嗎?我應該使用map,foldl或foldr函數。

編輯:

- fun less (e, L) = 
= let 
=  val acc = [] 
= in 
=  foldr (fn a => if a < e then a::acc else acc) acc L 
= end; 

仍然給我的錯誤,以下錯誤:

stdIn:241.3-241.54 Error: operator and operand don't agree [overload] 
    operator domain: 'Z * 'Y -> 'Y 
    operand:   'X -> 'X list 
    in expression: 
    foldr (fn a => if <exp> < <exp> then <exp> :: <exp> else acc) 

回答

1

該錯誤信息是明確的;因爲aint[]類型'a list,它們的類型不匹配。

問題是您爲任務選擇了錯誤的高階函數。該filter名單上的結構是最適合在這裏:

fun less (e, L) = filter (fn a => a < e) L 

你可以使用遞歸來實現less明確,或使用foldl/foldr積累過濾列表。但是,map在這裏似乎並不重要。

編輯:

我會給出提示有關使用foldl/foldr。您從空列表開始作爲累加器。每當元素小於e時,將一個元素添加到累加器;否則,返回累加器。

編輯2:

你忘了通過acc作爲lambda函數的參數:因爲您使用[]因爲只有累加器

fun less (e, L) = foldr (fn (a, acc) => if a < e then a::acc else acc) [] L 

而且let..in..end部分是多餘的。

+0

我應該使用地圖,foldl或foldr函數 – 2012-03-25 21:11:57

+0

@ aizen92:我只能給你一個提示。看到我更新的答案。 – pad 2012-03-25 21:19:19

+0

你的意思是什麼? – 2012-03-25 21:26:12