Considering the ref operator I'm having trouble to understand its application and the sense of the follow instructions:
1.
In this definition what am I defining?
- val ref x=ref 9;
val x = 9 : int
2.
and here what am I doing with ref x:= ref 12?
- val x= ref 8;
val x = ref 8 : int ref
- ref x := ref 12;
val it = () : unit
- x;
val it = ref 8 : int ref
val ref x = ref 9 defines x to be 9 - just as if you had written val x = 9. This is because ref is a constructor, so it's pattern matching the value ref 9 against the pattern ref x, which binds x to 9. Of course writing it like this instead of just writing val x = 9 makes very little sense.
When you write ref x := ref 12, you create a new ref (of type int ref ref) that refers to x. You then immediately change that new ref to refer to ref 12 rather than to x. Since the new ref you created is never stored anywhere where you might access, this will have no observable effect.
#newacct, #sepp2k I see this is from several years ago, but I found the discussion useful and wanted to contribute this output from Standard ML of New Jersey v110.79 [built: Tue Aug 8 16:57:33 2017]:
- val ref x = ref 9;
val x = 9 : int
Related
The one subject in SML which does not get much attention is 'records'.
I was wondering how to handle records in functions (as an argument or returented value). I know we can use the # operator in order to get an element of the record. But How should I pass the record to the function? is there a special pattern matching for that?
I have tried:
fun foo r = #1 r;
It ends with the following error:
Error: unresolved flex record
(can't tell what fields there are besides #1)
I didn't find any guide online which explains this part of records, in SML.
Also I tried:
fun foo {1=2,2=3} = 5;
And found out that tuples are actually syntax-sugar of records. Of Course I got the match warning, but at least it worked this time. The real question is how to handle 'generic' records. Could be helpful to see some examples or a reference to a guide on the subject.
It will be more then helpful to see also explanation about the signatures of those functions (as I mentioned records like {1=2,2=3} will get different signatures then {a=2,b=3}).
The one subject in SML which does not get much attention is 'records'.
I'm not sure what you mean. Standard textbooks on SML usually cover this. For example, ML for the Working Programmer, 2nd Ed. chapter 2, Names, Functions and Types, pp. 28 and on covers them. This book is free as a PDF, so you can read this chapter if you like.
If you read chapter 2, p. 34 it covers record patterns:
- val richardIII =
{ name = "Richard III"
, born = 1452
, crowned = 1483
, died = 1485
, quote = "Plots have I laid..."
};
> val richardIII =
{born = 1452, crowned = 1483, died = 1485, name = "Richard III",
quote = "Plots have I laid..."} :
{born : int, crowned : int, died : int, name : string, quote : string}
- val { name = richard_name, died = richard_died, ... } = richardIII;
> val richard_name = "Richard III" : string
val richard_died = 1485 : int
These record patterns are also possible in function arguments.
I recommend that you read a textbook on SML on this and other subjects.
StackOverflow is a poor format for reproducing one.
The real question is how to handle 'generic' records
Depending on what you mean by generic records, SML may not be able to do that.
For example, you can define the function
- fun f { x, y } = x + y;
> val f = fn : {x : int, y : int} -> int
But if you try to define one that extracts x and y from an arbitrary record without specifying the remaining record type,
- fun f { x, y, ... } = x + y;
! Toplevel input:
! fun f { x, y, ... } = x + y;
! ^^^^^^^^^^^^^
! Unresolved record pattern
Whereas if you specified the type of record,
- fun f ({ x, y, ... } : { x : int, y : int, z : int }) = x + y;
> val f = fn : {x : int, y : int, z : int} -> int
or equivalently via a type alias,
- type coord = { x : int, y : int, z : int };
> type coord = {x : int, y : int, z : int}
- fun f ({ x, y, ... } : coord) = x + y;
> val f = fn : {x : int, y : int, z : int} -> int
then that works as fine as using #x and #y:
- fun f (coord : coord) = #x coord + #y coord;
> val f = fn : {x : int, y : int, z : int} -> int
and without any kind of type annotation or inference, this will also fail to recognize the particular record type:
- fun f coord = #x coord + #y coord;
! Toplevel input:
! fun f coord = #x coord + #y coord;
! ^^
! Unresolved record pattern
So SML does not handle generic records in this sense even though it's technically possible to allow for this in a language. Perhaps this was not the meaning you went for. Perhaps record patterns were what you needed. I'll let you dig into the textbook material and resolve this.
Updated: As Andreas Rossberg suggested, I've simplified the examples a little.
I'm working on an assignment and was given the following function:
fun label (lb,ub) =
let val s = callcc (fn k =>let fun branch c = if (c < ub)
then (pushCP (k,branch,c+1);c)
else ub
in (pushCP(k,branch,lb+1);lb)
end)
in {value=s,dom=(lb,ub)}
end;
If you put a lower and upper bound of let's say 1 and 3into this function it would print
val it = {dom=(1,3), value=1}
What I am trying to figure out is if it is at all possible to get the value. In my notes it says two possible ways of doing this would be through #value(x) or by doing val {value=a,...} = x, but I get errors both ways with this.
Any clue what I am doing wrong?
It isn't clear what you are doing wrong since you haven't reproduced what you actually tried, but your notes are correct:
- val x = {dom=(1,3), value=1};
val x = {dom=(1,3),value=1} : {dom:int * int, value:int}
The first method is to use #value to extract the value field and #dom to extract the dom field:
- #value x;
val it = 1 : int
- #dom x;
val it = (1,3) : int * int
The second method is to use pattern matching. You can extract individual fields:
- val {value = a,...} = x;
val a = 1 : int
Or you can extract both fields at once:
- val {dom = a, value = b} = x;
val a = (1,3) : int * int
val b = 1 : int
In order for the above to work, x needs to be bound to the value. Perhaps you are trying to use this with an x which hasn't been given a val binding. You would need to have something like this:
val x = label(1,3)
I don't have all the relevant code so I can't test. If the above isn't enough to answer your question, you need to provide more details.
I have following piece of code:
let p = print_string("finished\n");;
let x0 = ref 0;;
class point =
object
val mutable x = incr x0; !x0
method get_x = x
method move d = x <- x + d
end
;;
print_int(new point#get_x);;
p;;
print_int(new point#get_x);;
p;;
Can't understand why the output is:
finished
12
My expectation is actually like:
1
finished
2
finished
Anyone can tell what's the correct order of executing this piece of code?
The main point of confusion is that your p isn't a function. It's just a value. In particular, it is the value () (known as unit). So when you evaluate p later in your code it has no effect. All the work was done when p was created.
If you want p to act like a function (which is what you seem to want), you should define it like this:
let p () = print_string "finished\n";;
And you should call it like this:
p ();;
I want to write something like
fun factorial 0 = 1
| factorial n = n * factorial(n-1);
but I don't get the "|" sign when i want to start the new line. I get something like:
fun factorial 0 = 1
= factorial n = n * factorial(n-1);
when I start the second line of code. If I hold shift and "\" I dont get the vertical bar, I get something else.
Since you say that the second line starts with an equal sign (=), it appear that you are writing your code directly into the interpreter?
In any case you have to write the pipe your self. The pipe is part of the SML syntax, and is used to "indicate" different function clauses, whereas the semicolon has a double meaning here. Doubling as being part of the SML syntax (though not strictly needed here) and as a special indicator to the interpreter (as explained below).
Most interpreters will keep reading data from stdin until it reads a semicolon, and first then will it start to interpret what you have written.
In the case of the SML/NJ interpreter, the first line is indicated by starting with a "-" and any subsequent lines starts with a "=". Note that the "-" and "=" signs are not interpreted as part of the final program.
An example of this can be seen below
- fun foo 0 y = 0
= | foo 1 y = y
= | foo x y = x*y;
val foo = fn : int -> int -> int
Here the last line is the output from the interpreter, when it reads the semicolon.
However we could also have declared two functions before writing the semicolon
- fun foo 0 y = 0
= | foo 1 y = y
= | foo x y = x * y
= fun fact 0 = 1
= | fact n = n * fact (n-1);
val foo = fn : int -> int -> int
val fact = fn : int -> int
Regarding the pipe, it depends on your keyboard layout, whether or not you will get it by typing shift+"\". However since your post contains multiple pipes, I suppose you already know how to write one.
fun temp(x) =
let val a = x
in if a mod (x-1) = 0 then x
else temp(x-1)
end;
this is example Standard ML code.
What I want to know is that
for example user call temp(10); then a = 10 and the temp(x-1) is called.
then the variable 'a' will change to 9. Can I keep it as 10 in Standard ML?
If your function contains val a = x, then for any invocation of temp(x), the value of a will be equal to the value of x. If you want to remember the value of a from a previous invocation when you recurse, you need to pass it around as a parameter like this:
fun temp_helper x a =
if a mod (x-1) = 0 then x
else temp_helper (x-1)
fun temp x = temp_helper x x
You could also make the helper function an inner function. If you do that, you can actually remove a as a parameter and instead close over a like this:
fun temp x =
let
val a = x
fun helper x =
if a mod (x-1) = 0 then x
else helper (x-1)
in
helper x
end