Search code examples
smlsmlnjnested-if

SML using destructors gives deleting INT0 LPAREN


The following function is using pattern matching.

fun f (x,0) = x
  | f (0,y) = y
  | f (x,y) = x+y;

I want to write this using if-else. This function of mine works fine:

fun f1(x, y) =
  if y = 0 then x
  else if x = 0 then y
  else x + y;

But I want to use #0 and #1 destructors (as an assignment). The following function

fun f2(arg) =
  if #0(arg) = 0 then #1(arg)
  else if #1(arg) = 0 then #0(arg)
  else #0(arg) + #1(arg);

gives the following error:

Error: syntax error: deleting  INT0 LPAREN

I have no idea what the error means and how to fix it.


Solution

  • There's two issues I can identify with your snippet.

    • SML tuples are 1-indexed, so it'd be #1 to extract the first component, not #0.
    • SML won't be able to infer the record's type correctly just from those usages, so you should annotate it explicitly: fun f2 (arg : int * int) = ....

    So, with a little modification:

    fun f2 (arg : int * int) =
        if #1 arg = 0 then #2 arg
        else if #2 arg = 0 then #1 arg
        else #1 arg + #2 arg
    

    works fine for me (compiled using MLton).

    In terms of style and semantics, the match version is far preferable. If you're going to go with the manual decision tree (which isn't the same sequence of tests as the pattern matching version would produce), you could at least hoist out the common access expressions:

    let
      val x = #1 arg
      val y = #2 arg
    in
      ...
    end