我有这个代码来过滤第一个字母为大写的字符串列表:
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)
我不知道如何解决这个问题。可以告诉我,这个错误是什么意思,以及如何解决这个问题。
谢谢:)
答案 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的列表。
所以这是一个有条理的功能。