2013-02-06 24 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的列表按照它们在参数列表中出现的顺序排列。

所以它是一个咖喱功能。