sml - Functors with multiple inputs in Standard ML -
high level question: how use functor
s multiple arguments in sml?
i've looked @ this, this, this , this(pdf). of them seem conflict in terms of structure
or functor
definition syntax, , none of them show other unary functor
.
specifics: i'm trying write web server in standard ml (you can see effort here), , have decided partition buffer
, parser
, tcpserver
chunks. buffer
, parser
both straightforward structure
s. idea tcpserver
handles listening/accepting logic, allows user specify appropriate buffering/parsing strategy passing other 2 in. i've got like
signature tcpserver = sig type sockaction type request val serve : int -> (request -> (inetsock.inet,socket.active socket.stream) socket.sock -> sockaction) -> 'u end functor server (buf : buffer) (par : parser) : tcpserver = struct type request = par.request datatype sockaction = close | leave_open local ... [eliding more definitions, including calls par.* , buf.* functions] ... fun serve port serverfn = let val s = inetsock.tcp.socket() in socket.ctl.setreuseaddr (s, true); socket.bind(s, inetsock.any port); socket.listen(s, 5); print "entering accept loop...\n"; acceptloop s [] serverfn end end end
the above seems accepted smlnj
...
- use "server.sml" ; [opening server.sml] type response = {body:string, headers:(string * string) list, httpversion:string, responsetype:string} val fst = fn : 'a * 'b -> 'a val snd = fn : 'a * 'b -> 'b val a_ = fn : 'a * 'b * 'c -> 'a val b_ = fn : 'a * 'b * 'c -> 'b val c_ = fn : 'a * 'b * 'c -> 'c val curry = fn : ('a * 'b -> 'c) -> 'a -> 'b -> 'c signature tcpserver = sig type sockaction type request val serve : int -> (request -> (inetsock.inet,socket.active socket.stream) socket.sock -> sockaction) -> 'a end functor httpserver(buf: sig type buffer val readinto : buffer -> ('a,socket.active socket.stream) socket.sock -> bufferstatus val new : int -> buffer val toslice : buffer -> word8arrayslice.slice val printbuffer : buffer -> unit end) : sig functor <functor> : <fctsig> end val = () : unit
... rejected mlton
.
~/projects/serve-sml $ mlton server.mlb error: server.sml 23.1. # (line "functor server...") syntax error: replacing functor fun. error: server.sml 24.1. syntax error: replacing struct asterisk. error: server.sml 87.1. syntax error found @ end. error: server.sml 88.0. parse error. ...
additionally, i'm not entirely sure how use definition once it's evaluated. in smlnj
, obvious fails:
- httpserver(defaultbuffer, defaultparser) ; stdin:1.2-1.12 error: unbound variable or constructor: httpserver stdin:2.7-3.1 error: unbound variable or constructor: defaultparser stdin:1.13-2.5 error: unbound variable or constructor: defaultbuffer -
can tell me i'm doing wrong? or point me piece of documentation?
your server
functor multiple arguments via currying. not work in plain sml, because not have higher-order functors (which sml/nj supports non-standard extension). need use uncurried form, introducing auxiliary structure, use tuple or record in core language:
functor server(x : sig structure buffer : buffer; structure parser : parser end) = ...x.buffer...x.parser... structure myserver = server(struct structure buffer = mybuffer; structure parser = myparser end)
obviously, pretty clumsy , verbose, @ least sml has syntactic sugar above, allowing keep auxiliary structure implicit:
functor server(structure buffer : buffer; structure parser : parser) = ...buffer...parser... structure myserver = server(structure buffer = mybuffer; structure parser = myparser)
but short gets in current sml.
Comments
Post a Comment