2013-02-06 23 views
4

我有這樣的代碼來過濾字符串列表中的第一個字母是大寫:SML:如何使用List.filter

fun f s = Char.isUpper(String.sub(s,0)); 
fun only_capitals (xs : string list) = List.filter(f , xs); 

但是,當編譯,我總是收到錯誤:

operator domain: 'Z -> bool 
operand:   (string -> bool) * string list 
    in expression: 
    List.filter (f,xs) 

我不知道如何解決這個問題。可以告訴我,這個錯誤是什麼意思,以及如何解決這個問題。

謝謝:)

+13

這似乎是Dan Grossman的(Coursera/U Washington)編程語言分配hw#3,問題#1。 「編寫一個函數'only_capitals',它接受一個字符串列表並返回一個字符串列表,該列表只包含以大寫字母開頭的字符串,假設所有字符串都至少有一個字符,使用'List.filter','Char .isUpper'和'String.sub'來製作1-2行解決方案。「 –

+1

這可能值得引用Grossman的講義第13頁來指導這項任務。 「例如,List.foldl((fn(x,y)=> x + y),0,[3,4,5])不會因爲List而進行類型檢查。foldl期望'a *'b - >'b函數,而不是三元組。正確的調用是List.foldl(fn(x,y)= x + y)0 [3,4,5] ...「它使用currying,是推力,這也讓我絆了一會兒。 – brntsllvn

回答

11

List.filter類型簽名是

val filter : ('a -> bool) -> 'a list -> 'a list 

所以,你需要給List.filter兩個不同的參數,這恰好是一個元組沒有一個說法。

+0

ah。thanks :)過濾器正在使用currying。 – hqt

+2

與ML中遇到的函數一樣必須;-) – Faiz

+1

@pad如果我錯了,請更正我,它不是* 2 *參數,只是調用List。過濾器「與第一個參數來獲取函數,然後調用_that returned_函數與第二個參數,對嗎? – Swanand

4

您需要將其更改爲:

fun only_capitals (xs : string list) = List.filter f xs 

filter需要兩個參數,一個函數f'a -> bool)和一個列表。

很容易混淆ML中傳遞元組的語法與其他語言中函數應用程序的sytax。

你也可以把它定義爲:在ML

val only_capitals = List.filter f 
+0

我相信一個更合適的措辭將是過濾器採用1參數(函數)並返回一個函數需要一個列表,過濾器不需要兩個參數 從文檔: val filter:('a - > bool) - >'list - >'list – andyortlieb

2

功能只能取一個說法。來自here的說明(另請參閱此處的說明和視頻)。

List.filter就是所謂的咖喱功能,所以List.filter f xs實際上是(List.filter f) xs其中List.filter f是一個函數。我們必須提供f (fn: a -> bool)作爲參數List.filter,而不是元組(f, xs)

這是一個簡單的例子。當我們撥打is_sorted 1時,我們會在其環境中關閉x。當我們將這個閉包稱爲2時,我們得到true,因爲1 <= 2

val is_sorted = fn x => (fn y => x <= y) 
val test0 = (is_sorted 1) 2 

val is_sorted = fn : int -> int -> bool 
val test0 = true : bool 
0

在SML文件,它指出:

過濾器FL 將f到每個元素x升的,由左到右,並返回其FX評價爲真正的那些x的列表按照它們在參數列表中出現的順序排列。

所以它是一個咖喱功能。