我有这个代码来过滤第一个字母为大写的字符串列表:
fun f s = Char.isUpper(String.sub(s,0));
fun only_capitals (xs : string list) = List.filter(f , xs);
Run Code Online (Sandbox Code Playgroud)
但是在编译时,我总是收到错误:
operator domain: 'Z -> bool
operand: (string -> bool) * string list
in expression:
List.filter (f,xs)
Run Code Online (Sandbox Code Playgroud)
我不知道如何解决这个问题.可以告诉我,这个错误是什么意思,以及如何解决这个问题.
谢谢 :)
pad*_*pad 12
类型签名List.filter
是
val filter : ('a -> bool) -> 'a list -> 'a list
Run Code Online (Sandbox Code Playgroud)
所以你需要提供List.filter
两个不同的参数,而不是一个恰好是元组的参数.
您需要将其更改为:
fun only_capitals (xs : string list) = List.filter f xs
Run Code Online (Sandbox Code Playgroud)
filter
接受 2 个参数,一个函数f
( 'a -> bool
) 和一个列表。
很容易将 ML 中传递元组的语法与其他语言中函数式应用程序的语法混淆。
您也可以将其定义为:
val only_capitals = List.filter f
Run Code Online (Sandbox Code Playgroud)
ML 中的函数只能采用一个参数。此处的说明(另请参阅此处的注释和视频)。
List.filter
就是所谓的柯里化函数,所以List.filter f xs
实际上(List.filter f) xs
是List.filter f
一个函数。我们必须提供f (fn: a -> bool)
作为参数List.filter
,而不是 tuple (f, xs)
。
这是一个简单的例子。当我们调用时,is_sorted 1
我们会在其环境中得到一个闭包x
。当我们用 2 调用这个闭包时,我们得到true
because 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
Run Code Online (Sandbox Code Playgroud)