SML/NJ中匹配Fifo.empty报错:变量需为构造器的解决方法咨询
Hey there! Let's break down why you're hitting that error and get your code working the right way.
First, let's unpack the error message: Error: variable found where constructor is required: Fifo.empty. This is telling you that in your pattern match (fun test Fifo.empty = true | test _ = false), you're trying to use Fifo.empty like a constructor—but it's not one.
In Standard ML, pattern matches on the left-hand side of a function definition can only use constructors (like Nil for built-in lists, or custom constructors you define with datatype), variables, or wildcards (_). Fifo.empty is actually a pre-defined value (an instance of an empty fifo queue), not a constructor, so it can't be directly used in a pattern like that.
The Correct Fixes
There are two straightforward, idiomatic ways to rewrite your test function:
Compare directly to
Fifo.empty
If the fifo type supports equality checking (which most standard implementations do), you can move the check into the function body instead of using pattern matching:fun test fifo = fifo = Fifo.emptyThis works because we're now evaluating an equality expression rather than trying to treat a value as a pattern.
Lean into
Fifo.isEmpty(your "temporary" fix is actually great!)
You mentioned usingFifo.isEmptyas a workaround, but this is actually the more robust and idiomatic approach. SML modules likeFifoprovide helper functions likeisEmptyto abstract away the internal details of the queue. Using this function avoids relying on direct equality checks (which could be inefficient or break if the fifo's internal structure changes later):fun test fifo = Fifo.isEmpty fifoDon't write this off as a hack—this is exactly how you're supposed to interact with abstract data types in SML!
Why Your Original Code Failed
To make this clearer, let's contrast with a valid pattern match example. If you had a custom list type:
datatype 'a mylist = Nil | Cons of 'a * 'a mylist
Here Nil is a constructor, so you could write:
fun test Nil = true | test _ = false
But Fifo.empty isn't a constructor—it's a value created using the module's internal constructors (which might even be hidden for encapsulation, so you can't use them directly anyway).
内容的提问来源于stack exchange,提问作者Gepapado

