let generateNextAssignList (assignList : (string * bool) list) : (string * bool) list * bool =
let carry = ref true in
let flag = ref true in
let inc_bools head =
let (var, boolean) = head in
if (boolean = false && !flag = true) then
(flag := false; carry := false; (var, Bool.not boolean))
else if (boolean = true && !flag = true) then
(var, Bool.not boolean)
else
(var, boolean) in
(List.rev (List.map inc_bools (List.rev assignList)), !carry);;
generateNextAssignList [("a", true); ("a", true); ("a", false)];;
I would like to have !carry
be false
in all cases, unless the list passed to the function is []
, or the bool in every tuple in the list is true
. So far, when I use the function, it is working properly, but !carry
is always true
, but is updating inside the function correctly. Is there a way to make it into a global variable that would fix this?
The issue is that !carry
is evaluated before the first element of the tuple in
List.rev (List.map inc_bools (List.rev assignList)), !carry
If you need to enforce the order of side-effect it is better to add an explicit let
:
let result = List.rev (List.map inc_bools (List.rev assignList)) in
result, !carry
( Note that there is a gap between your implementation and specification: carry is true if there is a value at the left of a false
value in assignList
. )
But it is probably better to avoid references by splitting your algorithm in two:
let generateNextAssignList assignList =
let rec reverse_until_first_false rev = function
| [] -> rev, []
| (v, false) :: q -> (v,true) :: rev, q
| (v, true) :: q -> reverse_until_first_false ((v, false) :: rev) q
in
let rev, rest = reverse_until_first_false [] (List.rev assignList) in
let carry = match rest with [] -> true | _ -> false in
let result = List.rev_append rest rev in
result, carry