问题
I've written a Mercury function to calculate the length of a list skeleton, but it doesn't compile and I don't understand why. I'd like to know what's going on here. (In the code below, the inst
, func
, and mode
statements are from the Mercury Reference Manual, sections 4.1 and 4.2. I'm writing a function body from the manual's declarations.)
:- inst my_listskel == bound( [] ; [free | my_listskel] ).
:- func my_length(list(T)) = int.
:- mode my_length(in(my_listskel)) = out.
my_length([]) = 0.
my_length([_ | Tl]) = Length :-
TailLength = my_length(Tl),
Length = 1 + TailLength.
That code gives me the following compiler error, where line 26 is TailLength = my_length(Tl)
:
mode_test.m:026: In clause for `my_length(in((mode_test.my_listskel))) = out':
mode_test.m:026: in argument 1 of call to function `mode_test.my_length'/1:
mode_test.m:026: mode error: variable `Tl' has instantiatedness `free',
mode_test.m:026: expected instantiatedness was `bound((list.[]) ;
mode_test.m:026: list.'[|]'(free, ...))'.
How does Tl
get an instantiatedness of free? My understanding is that Tl
can either be an instance of my_listskel
or the empty list, and that both of those would be bound, not free.
Is my problem here that I'm dealing with a partially-instantiated data structure (which isn't yet supported)? I suspect this might be the case. But the example is from the reference manual, which suggests that this ought to be supported.
来源:https://stackoverflow.com/questions/26684020/why-does-this-variable-have-an-instantiatedness-of-free