Question

function foo that has the type ’a * ’a -> int So I tried writing some prog:

fun foo(x,y)=6;(*here the type is ’a * ’b -> int*)
fun foo(x,x) =5; (*gives error cause of two x*)
fun foo(x,y) = if true then x else y; (give 'a * 'a -> 'a)

What should I do to get ’a * ’a -> int?

thanks

Was it helpful?

Solution 2

You're on the right track. It looks like you've understood that there are two parts to this problem: forcing x and y to have the same type, and forcing foo to return an integer.

You were close with fun foo (x,x) = 5;. I think you probably meant something like this:

fun foo (x,y) = if x=y then 1 else 0;

This gives ''a * ''a -> int, which is very close, but not quite what you need. ''a is not the same as 'a - while one dash means "any type", two dashes mean "any type which can be compared for equality". In other words, we've restricted the types just by saying x=y.

You've identified one way of forcing the types to be the same: putting them in the result of an if expression. Now all that's left is to turn the result of the if (which has type 'a) into an int. You could do that by putting it in a case expression, or passing it to another function with type 'a -> int.

Or you could try something else. Every element in a list has to have the same type. So there's another way to restrict the types of x and y: put them in the same list. Then you've just got to figure out how to turn that list into an int.

OTHER TIPS

I guess the trick is to use x and y in a such way that SML can infer they are of the same type. So, I thought that since lists only contain elements of the same type, we could put x and y in to a list and that will tell SML that they are of the same type. Then we can calculate the size of the list to return an int, and voila!

fun foo(x,y) = 
    let
       val items = x::y::[]
    in
       List.length items
    end

The gives type: 'a * 'a -> int

You had a good start with:

fun foo(x,y) = if true then x else y;

So, you should change only return type of function. You should return some Int. And go with an explicit type.

In your case example could be:

fun  foo(x :'a, y : 'a) = 1;

But this is explicit definition. As stated below by Nick Barnes, solution should involve adding variables to a list:

 fun f(x,y) = let val z = [x,y] in 0 end;

This one is short, and doesn't require any additional modules:

fun f (x, y) = 
  let val y = f (y, x) 
  in 5 end;

Though it doesn't terminate of course.

Here are three more ways to do it for your collection:

fun f1(x, y) = if false then f1(y,x) else 1

fun f2(x, y) = let val r = ref x
               in  r := y
                 ; 0
               end

fun f3(x, y) = let exception E of 'a
               in  (raise E x)
                   handle (E _) => (raise E y)
                                   handle E _ => 0
                end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top