1
val implies =
    fn x y = case x of false andalso case y of false => true
     | fn x y = case x of false andalso case y of true => true
     | fn x y = case x of true andalso case y of false => false
     | fn x y = case x of true andalso case y of true => true;  

I can't get this to compile. I'm relatively new to SML so not quite getting the general language and syntax. What have I done wrong?

Chucky
  • 1,701
  • 7
  • 28
  • 62

2 Answers2

7

There are various things wrong:

  • There is no arguments in implies to do pattern matching directly.
  • case x of is for pattern matching with specific values, not like if/else expression which accepts boolean expressions.
  • The syntax for lambda should start with fn x => ....

A quick fix:

fun implies x y =
    case (x, y) of
      (false, false) => true
    | (false, true) => true
    | (true, false) => false
    | (true, true) => true

which can be rewritten for readability as:

fun implies false false = true
  | implies false true = true
  | implies true false = false
  | implies true true = true

or more concise by using propositional logic rule:

fun implies x y = (not x) orelse y
pad
  • 41,040
  • 7
  • 92
  • 166
  • Tried the first suggestion, it's not compiling. Getting this error: tut01.sml:20.1 Error: syntax error: replacing BAR with WILD uncaught exception Compile [Compile: "syntax error"] raised at: ../compiler/Parse/main/smlfile.sml:15.24-15.46 ../compiler/TopLevel/interact/evalloop.sml:44.55 ../compiler/TopLevel/interact/evalloop.sml:296.17-296.20 – Chucky Apr 06 '12 at 14:12
  • Well, remove the first bar (see my update) since it is redundant. – pad Apr 06 '12 at 14:15
  • See my update, keep in mind that the first approach is the worst one. – pad Apr 06 '12 at 17:16
  • @pad, I think you were a bit to quick with the anonymous function/lambda? Hopefully you mean either `fn (x, y) => ...` or `fn x => fn y => ...` – Jesper.Reenberg Apr 06 '12 at 17:20
4

Regarding the anonymous functions,

fun implies x y = (not x) orelse y

can be written as

val implies = fn x => fn y => (not x) orelse y

however as you see, it doesn't really make any sense to do it this way (in this particular case).

Anonymous functions in SML only take one argument. Currying of arguments works because the fun keyword is syntactic sugar (also called a derived form) of

val rec implies = fn x => fn y =>
    case (x, y) of
      (x,y) => (not x) orelse y

The case is used because we could have had some pattern matching in the original function, which is then translated directly down into the case, and the rec is because the original function might have been recursive.

Thus the second example @pad gave is equivalent to:

val rec implies = fn x => fn y =>
    case (x, y) of
       (false, false) => true
     | (false, true) => true
     | (true, false) => false
     | (true, true) => true
Jesper.Reenberg
  • 5,944
  • 23
  • 31