Adding to a set in Ocaml -
i have fundamental issue in ocaml has been bugging me long time now. have pattern match compares input user , prints out concatenated string. works fine need add concatenated string set within pattern match. each time try error:
this expression has type ss.t = set.make(string).t expression expected of type string
i new ocaml , has taken many days , have not been able figure out. code pattern matching below:
type t = 0 | pproc of string | procdef of t * t module ss = set.make(string) let set2= ss.empty let concattoset s = list.fold_right ss.add [s] set2 let rec poc p = match p | 0 -> concattoset "0" | pproc x -> concattoset x | procdef (p1, p2) -> concattoset((poc p1)^"("^(poc p2)^")")
the error have :
procdef (p1, p2) -> concattoset((poc p1)^"("^(poc p2)^")");; ^^^^^^^^ error: expression has type ss.t = set.make(string).t expression expected of type string
i edited question available once peer reviewed. nevertheless, let's answer question (by way, don't "thanks!" , try give example can reproduce error.)
so, code looks :
type t = 0 | pproc of string | procdef of t * t module ss = set.make(string) let set2= ss.empty let concattoset s = list.fold_right ss.add [s] set2 let rec poc p = match p | 0 -> concattoset "0" | pproc x -> concattoset x | procdef (p1, p2) -> concattoset((poc p1)^"("^(poc p2)^")")
and error have :
procdef (p1, p2) -> concattoset((poc p1)^"("^(poc p2)^")");; ^^^^^^^^ error: expression has type ss.t = set.make(string).t expression expected of type string
first of all, set immutable ss.add
return new set, not unit
.
according this, type of concattoset
ss.elt -> ss.t
return type of poc
same type of concattoset "0")
.
that's because when compiler tries type function pattern matching infers type according returned each case of pattern matching :
let rec poc p = match p | 0 -> concattoset "0" | ...
here, p
of type t
because it's matched zero
, concattoset
of type string -> ss.t
concattoset "0"
of type ss.t
poc
of type t (*the type of p*) -> ss.t (the type returned concattoset "0"
.
when call concattoset ((poc p1) ^ poc p2))
, poc p1
expected string (concattoset : string -> ss.t) has type
ss.t(the return type of
poc p1`) , that's compiler told you.
an (ugly) idea of code write :
type t = 0 | pproc of string | procdef of t * t module ss = set.make(string) let concattoset ?s1 ?sep1 ?sep2 s2 set = let str = printf.sprintf "%s%s%s%s" (match s1 none -> "" | s -> s) (match sep1 none -> "" | s -> s) s2 (match sep2 none -> "" | s -> s) in ss.add str set;; let rec poc p set = match p | 0 -> concattoset "0" set | pproc x -> concattoset x set | procdef (p1, p2) -> concattoset ~s1:(poc p1) ~sep1:"(" ~sep2:")" (poc p2) set
but that's bit awkward , if types has multiple constructors rapidly hard write concattoset
.
what following (added timer more complex constructor):
let rec pp fmt = function | 0 -> format.fprintf fmt "0" | pproc x -> format.fprintf fmt "%s" x | procdef (p1, p2) -> format.fprintf fmt "%a(%a)" pp p1 pp p2 | timer(t,chan, var, p1, p2) -> format.fprintf fmt "timer%s(%s(%s).%a,%a)" t chan var pp p1 pp p2;; let concattoset s set = ss.add s set;; let poc p set = concattoset (format.asprintf "%a" pp p) set;;
so, pp
takes formatter (which can seen output buffer) prints in constructors necessary recursive calls. concattoset
simple ss.add
, poc
takes parameter of type t
, set , calls pp
formatter being string , gives new string concattoset
want have.
about %a
:
it may seem bit strange pp
expecting 2 arguments give 1 when call, example format.asprintf "%a" pp p
. well, actually, i'm not applying pp
p
, here, i'm giving 2 arguments printer said in documentation :
a: user-defined printer. take 2 arguments , apply first 1 outchan (the current output channel) , second argument. first argument must therefore have type out_channel -> 'b -> unit , second 'b. output produced function inserted in output of fprintf @ current point.
that's why writing format.asprintf "%a" (pp p)
wouldn't accepted compiler.
Comments
Post a Comment