7

I have the next code:

datatype expr = K of string| Number2 of expr * (expr list);
datatype number = Number1 of string | Number3 of int;
 fun append (nil, l2) = l2 
  | append (x::xs, l2) = x::append(xs, l2);
 fun map [] = []
    | map (h::t) = (What h)::(map t);
fun What (K x) = [Number1(x)]
    |What (Number2 (t,[])) = Number3(0)::What(t)
    |What (Number2 (y,a::b)) =  append(What(a), map(b));

It doesn't recognize the function "What".(unbound variable or constructor). How can I fix it, that it will know the function "What"?

Thanks.

Michael J. Barber
  • 24,518
  • 9
  • 68
  • 88
Adam Sh
  • 8,137
  • 22
  • 60
  • 75

2 Answers2

10

Declarations in SML work from top to bottom, so map doesn't see What. Switching the order won't help, as then What wouldn't see map, giving the same error. Instead, you need to declare the mutually recursive functions simultaneously using and:

fun map [] = []
  | map (h::t) = (What h)::(map t)
and What (K x) = [Number1(x)]
  | What (Number2 (t,[])) = Number3(0)::What(t)
  | What (Number2 (y,a::b)) =  append(What(a), map(b))
Michael J. Barber
  • 24,518
  • 9
  • 68
  • 88
3

You have to use and for mutual recursion. You have some other problems though in your code. What is clearly an expr -> number list, which means map must be expr list -> (number list) list, so in your final line you're trying to append a number list list to a number list. It's not at all clear what the code is meant to be doing though, so you might have to work out your intended logic on your own. There doesn't look to be any obvious way to write a function with the required type.

Nicholas Wilson
  • 9,435
  • 1
  • 41
  • 80
  • Thank you Nicholas, I just deal with this and I stack. "b" can be a list of expr. I just want to check each expr in that list and decide if it "Number1" or "Number3" or data type expr - all this I do by the function What. The Only idea is to use "map" to check each member in the list. But it give an error: "operand and operator are don't agree". Any idea? – Adam Sh Nov 04 '11 at 14:27
  • 2
    Your types are very confused. Firstly, yes: b is definitely a list of expr. They are all exprs: no Number1 or Number3s in b. You will have to explain to us what you are trying to do, because I don't think we have a chance of helping you otherwise. Do you realise that your map function is very different to the normal map? Perhaps that's the confusion. You are ignoring y as well; is that expr meant to be used for something? – Nicholas Wilson Nov 04 '11 at 18:26
  • 1
    Why my function is diffrent from the normal map? I will clarify my question: Number 2 is expr, and can be list of expr. Now, If it is a list of expr, So I want to check each member in that list, and to find out if it K or Number2. Then, I need to decide what to do with this member (It can be Number1 or Number3, my first two lines in What function), and make a list that contains only Number1 or Number3. so, My intuitive way is to use a map to check each member in "b", untul the end of the list, by using map function. Thank you. – Adam Sh Nov 04 '11 at 19:20