问题
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