%% $Id: objinst.mercury,v 1.1 2001/07/29 00:07:28 doug Exp $ %% http://www.bagley.org/~doug/shootout/ %% from Fergus Henderson :- module mytest. :- interface. :- import_module io. :- pred main(io__state::di, io__state::uo) is det. :- implementation. :- import_module bool, int, string, list. :- type toggle ---> toggle(toggle_value::bool). :- typeclass toggle(T) where [ func value(T) = bool, func 'value :='(T, bool) = T, func activate(T) = T ]. :- instance toggle(toggle) where [ func(value/1) is toggle_value, func('value :='/2) is 'toggle_value :=', activate(toggle(yes)) = toggle(no), activate(toggle(no)) = toggle(yes) ]. :- type nth_toggle ---> nth_toggle(base::toggle, counter::int, limit::int). :- func make_nth_toggle(bool, int) = nth_toggle. make_nth_toggle(Val, Max) = nth_toggle(toggle(Val), 0, Max). :- instance toggle(nth_toggle) where [ value(T) = T^base^value, 'value :='(T, V) = T^base^value := V, (activate(T) = NewT :- C = T^counter + 1, (if C >= T^limit then NewT = (T^counter := 0)^base := activate(T^base) else NewT = T^counter := C )) ]. main --> io__command_line_arguments(Args), { N = (if Args = [Arg], to_int(Arg, N0) then N0 else 1) }, { Toggle1 = toggle(yes) }, loop(5, (pred(T0::in, T::out, di, uo) is det --> { T = T0^activate }, write_string(if T^value = yes then "true" else "false"), nl), Toggle1, Toggle2), loop(N, (pred(_T0::in, T::out, di, uo) is det --> { T = toggle(yes) }), Toggle2, _Toggle3), nl, { Toggle4 = make_nth_toggle(yes, 3) }, loop(8, (pred(T0::in, T::out, di, uo) is det --> { T = T0^activate }, write_string(if T^value = yes then "true" else "false"), nl), Toggle4, Toggle5), loop(N, (pred(_T0::in, T::out, di, uo) is det --> { T = make_nth_toggle(yes, 3) }), Toggle5, _Toggle6). :- pred loop(int, pred(T1, T1, T2, T2), T1, T1, T2, T2). :- mode loop(in, pred(in, out, di, uo) is det, in, out, di, uo) is det. loop(N, P, X0, X) --> (if { N = 0 } then { X = X0 } else P(X0, X1), loop(N - 1, P, X1, X) ).