[MLton-devel] Possible type-inference bug
Jesper Louis Andersen
jlouis@mongers.org
Tue, 14 Oct 2003 01:29:47 +0200
First, I do not know if this is a bug in the type-inference pass,
but what I have here is being checked without problems by SML/NJ
110.42 but not by mlton. I did not completely understand the known
bug, so there is a caveat that I might have hit exactly that (read:
I have not yet dug into that bug and why it is a bug and the SML
code example in question).
First the MLton version:
(MLton MLTONVERSION (built Mon Oct 13 01:22:54 2003 on sarah))
What is the code in question? It is a little Xhtml library I've toyed
with. The idea is that XML can be represented by four operations:
concatenation (op+++): xt +++ xt'; xt,xt' is XML trees, will yield
a new XML tree which is the concatenation of these 2
injection (op<<<): tag <<< xt; xt is XML tree, tag is a XML tag
will yield the XML tree where xt is injected inside tag, eg
<tag>xt</tag>.
pure strings (op$): $ str yields the string str
augmentation(op!): t ! (pl), will augment the tag with parameters
in the parameter list pl, eg:
(A ! ("href", "http://www.mlton.org")) <<< ($ "mlton.org")
yields:
<a href="http://www.mlton.org">mlton.org</a>
Thus we now have a nice little combinator library for producing
XML, so we build an Xhtml structure from it, pulling the relevant
information out. But of course there is a flatten function which
takes an XML tree to a string. Performance has not been into
consideration yet in this. It is the place where I expect the
MLton profiler to be able to do wonders.
Anyway, here is what happens in MLton:
Error: Xhtml.sml 155.1: unable to infer type for HEAD
type: string * ??? list
dec: val HEAD = X.buildTag ("head", [])
Error: Xhtml.sml 156.1: unable to infer type for TITLE
type: string * ??? list
dec: val TITLE = X.buildTag ("title", [])
Error: Xhtml.sml 157.1: unable to infer type for BODY
type: string * ??? list
dec: val BODY = X.buildTag ("body", [])
Error: Xhtml.sml 158.1: unable to infer type for H1
type: string * ??? list
dec: val H1 = X.buildTag ("h1", [])
Error: Xhtml.sml 159.1: unable to infer type for H2
type: string * ??? list
dec: val H2 = X.buildTag ("h2", [])
Error: Xhtml.sml 160.1: unable to infer type for H3
type: string * ??? list
dec: val H3 = X.buildTag ("h3", [])
Error: Xhtml.sml 161.1: unable to infer type for H4
type: string * ??? list
dec: val H4 = X.buildTag ("h4", [])
Error: Xhtml.sml 162.1: unable to infer type for H6
type: string * ??? list
dec: val H6 = X.buildTag ("h6", [])
Error: Xhtml.sml 163.1: unable to infer type for P
type: string * ??? list
dec: val P = X.buildTag ("p", [])
Error: Xhtml.sml 164.1: unable to infer type for ADDRESS
type: string * ??? list
dec: val ADDRESS = X.buildTag ("address", [])
compilation aborted: elaborate reported errors
---------------------------------------------------------------
But for SML/NJ 110.42:
jlouis@sarah$ sml Xhtml.sml
Standard ML of New Jersey v110.42 [FLINT v1.5], October 16, 2002
[opening Xhtml.sml]
[autoloading]
[autoloading done]
signature XML =
sig
type parameter
type tag
datatype xmltree
= Concat of xmltree * xmltree
| Inject of tag * xmltree
| Str of string
| Tag of tag
val augment : tag * parameter list -> tag
val buildString : string -> xmltree
val buildTag : string * (string * string) list -> tag
val flatten : xmltree -> string
end
structure Xml : XML
signature XML_STRUCTS =
sig
structure Xml :
sig
type parameter
type tag
datatype xmltree
= Concat of xmltree * xmltree
| Inject of tag * xmltree
| Str of string
| Tag of tag
val augment : tag * parameter list -> tag
val buildString : string -> xmltree
val buildTag : string * (string * string) list -> tag
val flatten : xmltree -> string
end
end
signature XML_COMBINATORS =
sig
structure Xml :
sig
type parameter
type tag
datatype xmltree
= Concat of xmltree * xmltree
| Inject of tag * xmltree
| Str of string
| Tag of tag
val augment : tag * parameter list -> tag
val buildString : string -> xmltree
val buildTag : string * (string * string) list -> tag
val flatten : xmltree -> string
end
val +++ : Xml.xmltree * Xml.xmltree -> Xml.xmltree
val <<< : Xml.tag * Xml.xmltree -> Xml.xmltree
val ! : Xml.tag * Xml.parameter list -> Xml.tag
val $ : string -> Xml.xmltree
end
functor XmlCombinators(<param>: sig structure Xml : <sig> end) :
sig
structure Xml : <sig>
val +++ : Xml.xmltree * Xml.xmltree -> Xml.xmltree
val <<< : Xml.tag * Xml.xmltree -> Xml.xmltree
val ! : Xml.tag * Xml.parameter list -> Xml.tag
val $ : string -> Xml.xmltree
end
signature XHTML_STRUCTS =
sig
structure X :
sig
type parameter
type tag
datatype xmltree
= Concat of xmltree * xmltree
| Inject of tag * xmltree
| Str of string
| Tag of tag
val augment : tag * parameter list -> tag
val buildString : string -> xmltree
val buildTag : string * (string * string) list -> tag
val flatten : xmltree -> string
end
end
signature XHTML =
sig
structure X :
sig
type parameter
type tag
datatype xmltree
= Concat of xmltree * xmltree
| Inject of tag * xmltree
| Str of string
| Tag of tag
val augment : tag * parameter list -> tag
val buildString : string -> xmltree
val buildTag : string * (string * string) list -> tag
val flatten : xmltree -> string
end
val XHTML_Header : string
val HTML : X.tag
val HEAD : X.tag
val TITLE : X.tag
val BODY : X.tag
val H1 : X.tag
val H2 : X.tag
val H3 : X.tag
val H4 : X.tag
val H6 : X.tag
val P : X.tag
val ADDRESS : X.tag
val buildRef : string -> X.tag
val comment : string -> string
val +++ : X.xmltree * X.xmltree -> X.xmltree
val <<< : X.tag * X.xmltree -> X.xmltree
val ! : X.tag * X.parameter list -> X.tag
val $ : string -> X.xmltree
end
functor Xhtml(<param>: sig structure XmlCombinators : <sig> end) :
sig
structure X : <sig>
val XHTML_Header : string
val HTML : X.tag
val HEAD : X.tag
val TITLE : X.tag
val BODY : X.tag
val H1 : X.tag
val H2 : X.tag
val H3 : X.tag
val H4 : X.tag
val H6 : X.tag
val P : X.tag
val ADDRESS : X.tag
val buildRef : string -> X.tag
val comment : string -> string
val +++ : X.xmltree * X.xmltree -> X.xmltree
val <<< : X.tag * X.xmltree -> X.xmltree
val ! : X.tag * X.parameter list -> X.tag
val $ : string -> X.xmltree
end
structure Combinators : XML_COMBINATORS
structure Xhtml : XHTML
- open Xhtml;
opening Xhtml
structure X :
sig
type parameter = string * string
type tag = string * parameter list
datatype xmltree
= Concat of xmltree * xmltree
| Inject of tag * xmltree
| Str of string
| Tag of tag
val augment : tag * parameter list -> tag
val buildString : string -> xmltree
val buildTag : string * (string * string) list -> tag
val flatten : xmltree -> string
end
val XHTML_Header : string
val HTML : X.tag
val HEAD : X.tag
val TITLE : X.tag
val BODY : X.tag
val H1 : X.tag
val H2 : X.tag
val H3 : X.tag
val H4 : X.tag
val H6 : X.tag
val P : X.tag
val ADDRESS : X.tag
val buildRef : string -> X.tag
val comment : string -> string
val +++ : X.xmltree * X.xmltree -> X.xmltree
val <<< : X.tag * X.xmltree -> X.xmltree
val ! : X.tag * X.parameter list -> X.tag
val $ : string -> X.xmltree
- ^D
--------------------------------------------------------------------
And the code in question. If you want it for http download in the
future, then do please tell:
signature XML =
sig
type parameter
(*
* TODO Build up a tagtype, which sets options on where a given
* tag can be used
*)
type tag
datatype xmltree = Str of string
| Tag of tag
| Concat of xmltree * xmltree
| Inject of tag * xmltree
val augment : tag * parameter list -> tag
val buildString : string -> xmltree
val buildTag : string * ((string * string) list) -> tag
val flatten : xmltree -> string
end
structure Xml : XML =
struct
type parameter = (string * string)
type tag = (string * parameter list)
datatype xmltree = Str of string
| Tag of tag
| Concat of xmltree * xmltree
| Inject of tag * xmltree
fun augment ((tagname, params), nparams) =
(tagname, params @ nparams)
fun buildString str = Str str
fun buildTag (name, paramlist) = (name, paramlist)
fun buildParamlist params =
String.concat (
map (fn (param, value) =>
String.concat [param, "=\"", value, "\" "]
) params
)
fun flatten x =
case x of
Str str => str
| Tag (str, params) =>
String.concat ["<", str, " ", buildParamlist params, "/>"]
| Concat (t1, t2) =>
String.concat [flatten t1, flatten t2]
| Inject ((str, params), tree) =>
String.concat ["<", str, " ", buildParamlist params, ">",
flatten tree,
"</", str, ">"
]
end
signature XML_STRUCTS =
sig
structure Xml : XML
end
signature XML_COMBINATORS =
sig
include XML_STRUCTS
val +++ : Xml.xmltree * Xml.xmltree -> Xml.xmltree
val <<< : Xml.tag * Xml.xmltree -> Xml.xmltree
val ! : Xml.tag * Xml.parameter list -> Xml.tag
val $ : string -> Xml.xmltree
end
functor XmlCombinators (structure Xml : XML) : XML_COMBINATORS =
struct
structure Xml = Xml
infix 3 +++ (* Concatenation *)
infix 5 <<< (* Injection *)
infix 7 ! (* Augmentation *)
fun xt1 +++ xt2 = Xml.Concat (xt1, xt2)
fun tag <<< xt = Xml.Inject (tag, xt)
fun tag ! paramlist = Xml.augment (tag, paramlist)
fun $ str = Xml.buildString str
end
signature XHTML_STRUCTS =
sig
structure X : XML
end
signature XHTML =
sig
include XHTML_STRUCTS
val XHTML_Header : string
val HTML : X.tag
val HEAD : X.tag
val TITLE : X.tag
val BODY : X.tag
val H1 : X.tag
val H2 : X.tag
val H3 : X.tag
val H4 : X.tag
val H6 : X.tag
val P : X.tag
val ADDRESS : X.tag
val buildRef : string -> X.tag
val comment : string -> string
val +++ : X.xmltree * X.xmltree -> X.xmltree
val <<< : X.tag * X.xmltree -> X.xmltree
val ! : X.tag * X.parameter list -> X.tag
val $ : string -> X.xmltree
end
functor Xhtml (structure XmlCombinators : XML_COMBINATORS) : XHTML =
struct
structure X = XmlCombinators.Xml
(*
* This could be rewritten into the XML code but this is simpler for
* the time being
*)
val XHTML_Header =
String.concatWith "\n" [
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 0.1//EN\"",
" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">"
]
val HTML = X.buildTag
("html", [("xmlns", "http://www.w3.org/1999/xhtml"),
("xml:lang", "en")
])
val HEAD = X.buildTag ("head", [])
val TITLE = X.buildTag ("title", [])
val BODY = X.buildTag ("body", [])
val H1 = X.buildTag ("h1", [])
val H2 = X.buildTag ("h2", [])
val H3 = X.buildTag ("h3", [])
val H4 = X.buildTag ("h4", [])
val H6 = X.buildTag ("h6", [])
val P = X.buildTag ("p", [])
val ADDRESS = X.buildTag ("address", [])
fun buildRef r = X.buildTag ("a", [("href", r)])
fun comment com = String.concat ["<!-- ", com, "-->"]
val +++ = XmlCombinators.+++
val <<< = XmlCombinators.<<<
val ! = XmlCombinators.!
val $ = XmlCombinators.$
val flatten = X.flatten
end
structure Combinators = XmlCombinators(structure Xml = Xml)
structure Xhtml = Xhtml(structure XmlCombinators = Combinators)
(*
structure MyHomepage = J_Mongers_Org(structure Xhtml = Xhtml)
*)
--
j.
-------------------------------------------------------
This SF.net email is sponsored by: SF.net Giveback Program.
SourceForge.net hosts over 70,000 Open Source Projects.
See the people who have HELPED US provide better services:
Click here: http://sourceforge.net/supporters.php
_______________________________________________
MLton-devel mailing list
MLton-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mlton-devel