How to use List.filter?
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.
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
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
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.