Question

I have the following code:

 - exception Negative of string;
> exn Negative = fn : string -> exn
 - local fun fact 0 =1
            | fact n = n* fact(n-1)
    in
            fun factorial n=
            if n >= 0 then fact n
            else
            raise Negative "Insert a positive number!!!"
            handle Negative msg => 0
    end;

What is wrong with it?? I get the error:

! Toplevel input:
!       handle Negative msg => 0
!                              ^
! Type clash: expression of type
!   int
! cannot have type
!   exn

How can I fix it? I want the function to return 0, by means of exceptions, if the user enters a negative number.

I am also wondering how to display a message when the user enters a negative number, since print() returns unit, but the rest of the function returns int;

Was it helpful?

Solution

The precedence of raise and handle is a bit weird in SML. What you have written groups as

raise ((Negative "...") handle Negative msg => 0)

Consequently, you need to add parentheses around the if to get the right meaning.

On the other hand, I don't understand why you raise an exception just to catch it right away. Why not simply return 0 in the else branch?

Edit: If you want to print something and then return a result, use the semicolon operator:

(print "error"; 0)

However, I would strongly advise against doing that inside the factorial function. It's better to keep I/O and error handling separate from basic computational logic.

OTHER TIPS

Here is a number of ways you can fix your code:

local
  fun fact 0 = 1
    | fact n = n * fact (n-1)
in
  (* By using the built-in exception Domain *)
  fun factorial n =
      if n < 0 then raise Domain else fact n

  (* Or by defining factorial for negative input *)
  fun factorial n =
      if n < 0 then -1 * fact (-n) else fact n

  (* Or by extending the type for "no result" *)
  fun factorial n =
      if n < 0 then NONE else SOME (fact n)
end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top