[mercury-users] typeclass / collections / unexplainable behaviour
Jörg Roman Rudnick
joerg.rudnick at t-online.de
Mon Oct 16 17:10:17 AEST 2006
Dear Mercury team,
having done type classes of collections by passing members wrapped
(once, of course) so far, I've just stumbled over some strange behaviour:
In some cases extraction seems to return multiply wrapped members.
My example code represents the most simple case of this phenomenon;
other variations lead to a segmentation violation.
% --- snip
------------------------------------------------------------------
:-module test0.
:-interface.
:-import_module io.
:-pred main(io::di, io::uo) is det.
%%%===========================================================
:-implementation.
:-import_module queue.
%%% Node:
:-type node ---> node.
:-typeclass fringeNode(T) where [].
:-instance fringeNode(node) where [].
%%% Fringe:
:-type wrapper(T) ---> wrap(T).
:-typeclass fringeW(Fringe, Wrapper) <= (Fringe -> Wrapper) where [
pred firstW(Fringe::in, Wrapper::out) is semidet,
func insertW(Wrapper, Fringe)= Fringe
].
:-instance fringeW(queue(T), wrapper(T)) <= fringeNode(T) where [
(firstW(Queue, wrap(First)) :- queue.first(Queue, First)),
(insertW(wrap(Node), Queue)= queue.put(Queue, Node))
].
:-pred suche(NodeT::in, FringeT::in, io::di, io::uo) is det
<= fringeW(FringeT, wrapper(NodeT)).
suche(Node, EmptyFringe, !IO) :-
Fringe = insertW(wrap(Node), EmptyFringe),
write_string("fringe: ", !IO), write(Fringe, !IO), nl(!IO),
(if firstW(Fringe, Wrap) then
write_string("wrapped first: ", !IO), write(Wrap, !IO), nl(!IO)
else true).
%%% to prevent ambiguity with (pred (queue.queue(T))):
:-func emptyQueue= queue(node).
emptyQueue= queue.init.
main(!IO) :-
suche(node, emptyQueue, !IO).
% --- snap
------------------------------------------------------------------
Here the output:
$> ./test0
fringe: [] - [node]
wrapped first: wrap(wrap(node))
The debugger is a bit terse - actually, the doubling of wrappers seems
to appear before calling write/3, as in other examples, I could unwrap
`wrap(wrap(node))', receiving `wrap(node)'. Moreover, with nested
fringeNode type variables (e.g., `nest(...)') I made an observation that
the outer functor is also multiplied (e.g., `wrap(nest(wrap(nest(...))))'):
-------------------------
22: 13 5 CALL pred queue.first/2-0 (semidet) queue.m:178
(test0.m:21)
mdb> p
first([] - [node], _)
mdb>
23: 13 5 EXIT pred queue.first/2-0 (semidet) queue.m:178
(test0.m:21)
mdb> p
first([] - [node], node)
mdb>
24: 12 4 EXIT pred
test0.ClassMethod_for_test0__fringeW____queue__queue__arity1__test0__wrapper__arity1______test0__firstW_2/2-0
(semidet) test0.m:21
mdb> p
ClassMethod_for_test0__fringeW____queue__queue__arity1__test0__wrapper__arity1______test0__firstW_2(-([],
[node]), wrap(node))
mdb>
25: 11 3 EXIT pred test0.firstW/2-0 (semidet) (test0.m:30)
mdb> p
firstW([] - [node], wrap(node))
mdb>
26: 4 2 THEN pred test0.suche/4-0 (det) c9;t; test0.m:31
mdb> p
suche(wrap(node), [] - [], _, _)
mdb> P
Node (arg 1) wrap(node)
EmptyFringe (arg 2) [] - []
Fringe [] - [node]
TypeInfoIndex 1
Wrap wrap(wrap(node))
mdb>
27: 14 3 CALL pred io.write_string/3-0 (det) io.m:6309
(test0.m:31)
mdb>
wrapped first: 28: 14 3 EXIT pred io.write_string/3-0 (det)
io.m:6309 (test0.m:31)
mdb>
29: 15 3 CALL pred io.write/3-0 (det) io.m:3796 (test0.m:31)
mdb> p
write(wrap(wrap(node)), _, _)
mdb>
-----------------------
As I got notice work (which I am greatly looking forward to :-) will be
done on type classes in the next future, I just wanted to report this
incident. Perhaps it is of interest.
All the best,
Nick
-------------- next part --------------
A non-text attachment was scrubbed...
Name: test0.m
Type: text/x-objcsrc
Size: 1228 bytes
Desc: not available
URL: <http://lists.mercurylang.org/archives/users/attachments/20061016/07350f9b/attachment.bin>
More information about the users
mailing list