Reputation: 30284
I have this code to filter list of string that the first letter is capital:
fun f s = Char.isUpper(String.sub(s,0));
fun only_capitals (xs : string list) = List.filter(f , xs);
But when compile, I always receive error :
operator domain: 'Z -> bool
operand: (string -> bool) * string list
in expression:
List.filter (f,xs)
What does this error mean? How to fix it?
Upvotes: 9
Views: 15060
Reputation: 11
In the SML document, the filter function in the List
structure listed as
filter f l
where it takes curried arguments f
and l
Instead of passing the arguments in a tuple, you have to provide a function and the list separated by spaces. The answer will be like this
fun only_capitals (xs: string list) =
List.filter (fn s => Char.isUpper(String.sub(s,0))) xs
Upvotes: 1
Reputation: 79
In the SML document, it states that:
filter f l applies f to each element x of l, from left to right, and returns the list of those x for which f x evaluated to true, in the same order as they occurred in the argument list.
So it is a curried function.
Upvotes: 3
Reputation: 2341
Functions in ML can take only one argument. Description from here (see also notes and video there).
List.filter
is so called curried function, so List.filter f xs
is actually (List.filter f) xs
where List.filter f
is a function. We have to provide f (fn: a -> bool)
as an argument to List.filter
, not tuple (f, xs)
.
Here is a simple example. When we call is_sorted 1
we get a closure with x
in its environment. When we call this closure with 2 we get 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
Upvotes: 5
Reputation: 41290
Type signature of List.filter
is
val filter : ('a -> bool) -> 'a list -> 'a list
So you need to give List.filter
two distinct arguments, not one argument which happens to be a tuple.
Upvotes: 16
Reputation: 16265
You need to change it to:
fun only_capitals (xs : string list) = List.filter f xs
filter
takes 2 arguments, a function f
('a -> bool
) and a list.
It's easy to confuse syntax of passing a tuple in ML with the sytax of functional application in other languages.
You could also define it as:
val only_capitals = List.filter f
Upvotes: 8