问题
Suppose I have to update a list with each call to a function, such that, the previous element of the list are preserved.
Here is my attempt:
local
val all_list = [];
in
fun insert (x:int) : string = int2string (list_len( ((all_list@[x])) ) )
end;
The problem is that each time I call to insert, I get the output "1", which indicates that the list is initiated to []
again.
However I was expecting output of "1"
for the first call to insert, and "2"
for the second call,...etc.
I am not able to come with a workaround. How should it be done?
回答1:
You need to use side-effects. Most of the time functional programmers prefer to use pure functions, which don't have side effects. Your implementation is a pure function, so it will always return the same value for the same input (and in your case it returns the same value for any input).
You can deal with that by using a reference.
A crash course on references in Standard ML:
- use
ref
to create a new reference,ref
has type'a -> 'a ref
, so it packs an arbitrary value into a reference cell, which you can modify later; !
is for unpacking a reference:(!) : 'a ref -> 'a
, in most imperative languages this operation is implicit, but not in SML or OCaml;(:=) : 'a ref * 'a -> unit
is an infix operator used for modifying references, here is how you increment the contents of an integer reference:r := !r + 1
.
The above gives us the following code (I prepend x
s onto the list, instead of appending them):
local
val rxs = ref []
in
fun insert (x:int) : string =
(rxs := x :: !rxs;
Int.toString (length (!rxs)))
end
回答2:
Values are immutable in SML. insert
is defined in a context in which the value of all_list
is []
and nothing about your code changes that value.
all_list@[x]
doesn't mutate the value all_list
-- it returns a brand new list, one which your code promptly discards (after taking its length).
Using reference types (one of SML's impure features) it is possible to do what you seem to be trying to do, but the resulting code wouldn't be idiomatic SML. It would break referential transparency (the desirable feature of functional programming languages where a function called with identical inputs yields identical outputs).
来源:https://stackoverflow.com/questions/41304765/how-to-keep-elements-in-list-through-out-the-program-in-sml