Search code examples
smlml

The usage of before in ML


ML's before is described in http://sml-family.org/Basis/general.html as

a before b returns a. It provides a notational shorthand for evaluating a, then b, before returning the value of a.

When I tried to use this command expecting x = 4 and (4+1) is evaluated

val x = (3+1 before 4+1)

I have the error message:

Standard ML of New Jersey v110.78 [built: Sun Apr 26 01:06:11 2015]
- stdIn:1.11-1.25 Error: operator and operand don't agree [overload conflict]
  operator domain: [+ ty] * unit
  operand:         [+ ty] * [+ ty]
  in expression:
    (3 + 1 before 4 + 1)
- 

What might be wrong?

Edit

From Matt's answer, I should have used

val x = (3+1 before print "<end>")

I also found that before is used to close the stream after processing some FileIO functions.

(* http://stackoverflow.com/questions/2168029/open-file-in-mlsmlnj *)
val infile = "input.txt" ;

(*  reading from file follow this to list of string per line *)
fun readlist (infile : string) = let 
    val ins = TextIO.openIn infile 
    fun loop ins = 
     case TextIO.inputLine ins of 
            SOME line => line :: loop ins 
          | NONE      => [] 
in 
    loop ins before TextIO.closeIn ins 
end ;

val pureGraph =  readlist(infile);

size (hd pureGraph)

Solution

  • From here, it says that the type of before is before : ('a * unit) -> 'a, and as your type error specifies, it is expecting the type of the second argument to be of type unit, however, you have supplied something of type int. Try doing val x = (3+1 before ()) and you should get the expected result. The intended purpose is to have the second argument be some sort of side affecting computation, such as manipulating a ref cell or doing some IO, which you want to run prior to evaluating your first argument. It seems that the following are the same:

    val x = e1 before e2
    

    and

    val x = let val a = e1
                val _ = e2
            in a end
    

    That said, before is not something I really use , so if anyone else has anything to add, comments are certainly welcome.