Reputation: 91
I had an Ocaml issue resolved earlier but I am wondering if there is a best way to optimize my solution as I have tried all avenues and since I am very new to Ocaml I cannot really figure it out. I have a pattern function that does pretty printing and then another function that adds to a set. The pretty printing function is as follows:
let rec processoperatorchange fmt = function
| Zero -> Format.fprintf fmt "0"
| Pproc x -> Format.fprintf fmt "%s" x
| Procdef (p1, x) -> Format.fprintf fmt "%s(%s)" p1 x
| Par (p1, p2) -> Format.fprintf fmt "(%a + %a)" processoperatorchange p1 processoperatorchange p2
| Concur(p1, p2) -> Format.fprintf fmt "(%a | %a)" processoperatorchange p1 processoperatorchange p2
| Rep(p) -> Format.fprintf fmt "!(%a)" processoperatorchange p
and I have another function that does the same thing but then changes the format of printing (this seems inefficient but I just cannot figure out the best way to make this better)
let rec processoperatorchange2 fmt = function
| Zero -> Format.fprintf fmt "0"
| Pproc x -> Format.fprintf fmt "%s" x
| Procdef (p1, x) -> Format.fprintf fmt "%s(%s)" p1 x
| Par (p1, p2) -> Format.fprintf fmt "(%a | %a)" processoperatorchange2 p1 processoperatorchange2 p2
| Concur(p1, p2) -> Format.fprintf fmt "(%a + %a)" processoperatorchange2 p1 processoperatorchange2 p2
| Rep(p) -> Format.fprintf fmt "!(%a)" processoperatorchange2 p
Based on these functions, I have another function that calls to add to a set:
let op_change p set = concattoset (Format.asprintf "%a" processoperatorchange p) set |>
concattoset (Format.asprintf "%a" processoperatorchange2 p)
The code for concattoset
is:
let concattoset s set = SS.add s set
However, is there a way I can optimize this code such that I can condense the two functions processoperatorchange
and processoperatorchange2
into one function and add all this to the set? The main problem here is the I need to perform a change on a user defined input from the user and then add this change to a set and if there is no change, return an empty set but with the way its being done now, if there is no change I still add to the set because I do the function call to add to the set separately but can I condense all this into one function?
Upvotes: 1
Views: 528
Reputation: 66818
Your functions are the same except for the characters used for Par
and Concur
. You can pass these characters as parameters. This gives you a function like this:
let rec processoperatorchange pc cc fmt = function
| Zero -> Format.fprintf fmt "0"
| Pproc x -> Format.fprintf fmt "%s" x
| Procdef (p1, x) -> Format.fprintf fmt "%s(%s)" p1 x
| Par (p1, p2) ->
Format.fprintf fmt "(%a %c %a)"
(processoperatorchange pc cc) p1 pc (processoperatorchange pc cc) p2
| Concur(p1, p2) ->
Format.fprintf fmt "(%a %c %a)"
(processoperatorchange pc cc) p1 cc (processoperatorchange pc cc) p2
| Rep(p) ->
Format.fprintf fmt "!(%a)"
(processoperatorchange pc cc) p
If you call this function like this:
processoperatorchange '+' '|'
it acts like your original processoperator
function. If you call it like this:
processoperatorchange '|' '+'
it acts like processoperator2
.
So you can rewrite op_change
like this:
let op_change p set =
concattoset (Format.asprintf "%a" (processoperatorchange '+' '|') p) set |>
concattoset (Format.asprintf "%a" (processoperatorchange '|' '+') p)
Upvotes: 2