SML:如何使用List.filter

时间:2013-02-06 10:19:29

标签: list filter sml

我有这个代码来过滤第一个字母为大写的字符串列表:

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)

我不知道如何解决这个问题。可以告诉我,这个错误是什么意思,以及如何解决这个问题。

谢谢:)

4 个答案:

答案 0 :(得分:12)

List.filter的类型签名是

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

所以你需要给List.filter两个不同的参数,不是一个碰巧是元组的参数

答案 1 :(得分:4)

您需要将其更改为:

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

filter需要2个参数,一个函数f'a -> bool)和一个列表。

很容易混淆ML中传递元组的语法与其他语言中的功能应用程序的sytax。

您也可以将其定义为:

val only_capitals = List.filter f

答案 2 :(得分:3)

ML中的函数只能使用一个参数。来自here的说明(另请参阅说明和视频)。

List.filter是所谓的curried函数,因此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

答案 3 :(得分:1)

在SML文档中,它声明:

过滤f l     将f从左到右应用于l的每个元素x,并以与参数列表中出现的顺序相同的顺序返回f x求值为true的那些x的列表。

所以这是一个有条理的功能。