7

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

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

5 回答 5

15

List.filteris的类型签名

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

所以你需要给出List.filter两个不同的参数,而不是一个恰好是 tuple 的参数

于 2013-02-06T10:23:01.593 回答
5

您需要将其更改为:

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

filter接受 2 个参数,一个函数f( 'a -> bool) 和一个列表。

很容易将 ML 中传递元组的语法与其他语言中函数式应用程序的语法混淆。

您也可以将其定义为:

val only_capitals = List.filter f
于 2013-02-06T10:23:09.360 回答
4

ML 中的函数只能接受一个参数。此处的描述(另请参阅此处的注释和视频)。

List.filter就是所谓的柯里化函数,List.filter f xs其实(List.filter f) xswhereList.filter f是函数。我们必须提供f (fn: a -> bool)作为参数List.filter,而不是 tuple (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
于 2013-10-30T11:49:15.937 回答
2

在 SML 文档中,它指出:

filter fl 从左到右将 f 应用于 l 的每个元素 x,并返回 fx 评估为 true 的那些 x 的列表,其顺序与它们在参数列表中出现的顺序相同。

所以它是一个柯里化函数。

于 2014-10-24T19:30:02.997 回答
0

在 SML 文档中,List结构中的过滤器函数列为

filter f l

它需要咖喱论点fl

您必须提供一个函数和由空格分隔的列表,而不是在元组中传递参数。答案会是这样

fun only_capitals (xs: string list) = 
    List.filter (fn s => Char.isUpper(String.sub(s,0))) xs
于 2022-02-20T15:16:15.750 回答