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?
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)
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.