When I try to write something like
fun test Fifo.empty = true
| test _ = false`
I get an error message that says Error: variable found where constructor is required: Fifo.empty
. I'm really new to SML/NJ. Turns out it has something to do with Fifo.empty
being a longId, but I haven't figured out how to fix this, except by patching it by passing the Fifo.isEmpty
as an argument, but that's hardly a solution...
When you inspect the Fifo module,
- open Fifo;
[autoloading]
[library $SMLNJ-LIB/Util/smlnj-lib.cm is stable]
[autoloading done]
opening Fifo
datatype 'a fifo = ...
exception Dequeue
val empty : 'a fifo
(* and so on *)
you can see that Fifo.empty
is an 'a fifo value. To see how it's made,
- Fifo.empty;
val it = Q {front=[],rear=[]} : 'a fifo
Unfortunately the Q
datatype constructor of 'a fifo is hidden by the module being opaque (so the datatype
definition appears as "...
". When you define a datatype, its constructors (e.g. Q
) become both value constructors and pattern constructors, but when you declare values like Fifo.empty
using such value constructors, they don't also become pattern constructors.
I haven't figured out how to fix this, except by patching it by passing the
Fifo.isEmpty
as an argument, but that's hardly a solution...
I'm not sure why you would need to pass in Fifo.isEmpty
as an argument; can't you just refer to Fifo.isEmpty
in the function body? Perhaps there are dimensions to this problem you're not explaining.
How about the following:
fun test queue = Fifo.isEmpty queue
Or simply:
val test = Fifo.isEmpty
Generally, if you feel like passing in a bunch of library functions as arguments, you could instead consider building a higher-order module (functor) that takes another module as argument.