0

I'm using SML recently and I'm trying to solve a problem. I should create a function that accept an int list and return even int list, I've already created it :

 fun evens [] = [] |
 evens [x] = [x] |
 evens(x::xs) =
 case x mod 2 of
 0 => x::evens xs |
 1 => evens xs;

which gives the correct result but I need to use foldr this is what I came up with:

fun evens [] = [] |
evens(x::xs) =
case x mod 2 of
0 => foldr (op ::) evens xs [x]  |
1 => evens xs;

but it is not working, I'm still confused with how to use foldr in this case.

any advice?

John Coleman
  • 51,337
  • 7
  • 54
  • 119
MHK0
  • 9
  • 4

1 Answers1

1

First of all, with foldr you should be looking for a 1-line definition rather than a recursive definition using patterns and cases. The point of foldr is that it incorporates a common recursion pattern -- you just need to use the pattern.

The type of foldr is

fn : ('a * 'b -> 'b) -> 'b -> 'a list -> 'b

In your case 'b is int list and 'a is int. The 'b between the arrows in the middle of foldr's type is the seed value. It typically corresponds to a basis value. When you are constructing lists this basis value is typically []. Thus -- you need to concentrate on the key question of what should be folded over the list. In other words -- what function of type ('a * 'b -> 'b) should you pass to foldr? In your case you need to pass a function of type

int * int list -> int list

this should be a function which, when given an int and an int list either tacks the int onto the list (if it is even) or leaves the list alone. You could define this function ahead of time, define it using let, or just use an anonymous function.

Under the assumption that this is homework, I don't want to give a complete answer, but here is a function which uses foldr to obtain the positive entries in a list:

fun positives xs =
    foldr (fn (x,xs) => if x >= 0 then x::xs else xs) [] xs;
-
- positives [3,~2,4,5,0,~1,~1,5];
val it = [3,4,5,0,5] : int list
John Coleman
  • 51,337
  • 7
  • 54
  • 119