Here's an idea.
Tyson Richard DOWD
trd at cs.mu.oz.au
Thu Sep 4 21:47:33 AEST 1997
Anyone interested in having something like this added to the standard
library? I was just trying it out for novelty value, but it's actually
quite usable, which was a little unexpected.
%----------------------------------------------------------------------------
%
% A cute use of heterogenous lists, dynamic type-checking (using
% univ_to_type) and overloading of '.'.
%
% Instead of
%
% string__format("%d %d %f %s\n", [i(3), i(4), f(2.5), s("foo")], Str)
%
% we can can do
%
% sprintf("%d %d %f %s\n", [3, 4, 2.5, "foo"], Str)
%
% In fact, there's no need for string__poly_type (although this code
% just converts to it for simplicity).
%
% Unfortunately, overloading '.' like this causes problems - even
% [1,2,3] has two possible types. So you should put the '.' function
% in a module, then "use" it instead of "importing" it, and put a module
% qualifier before the list, eg:
%
% sprintf("%d %d %f %s\n", modulename:[3, 4, 2.5, "foo"], Str)
%
% Of course this removes some of the terseness of the code, but there's
% still a lot less parentheses to type...
:- module sprintf.
:- interface.
:- import_module io.
:- pred main(io__state, io__state).
:- mode main(di, uo) is det.
%----------------------------------------------------------------------------
:- implementation.
:- import_module require, string, list, std_util.
main -->
{ sprintf("%d %f %s %c\n", [20, 5.3, "foo", 'c'], Str) },
io__write_string(Str),
% And if you're going to use lists in the same
% namespace, you'll need to do something list this...
io__write(list:[1,2,3]),
io__nl.
%----------------------------------------------------------------------------
% Build a list of univs.
:- func sprintf:'.'(T, list(univ)) = (list(univ)).
:- mode sprintf:'.'(in, in) = (out) is det.
'.'(A, Xs) = list:'.'(univ(A),Xs).
% Use string__format to format the string.
:- pred sprintf__sprintf(string, list(univ), string).
:- mode sprintf__sprintf(in, in, out) is det.
sprintf__sprintf(FormatStr, UnivList, FinalStr) :-
list__map(sprintf__univ_to_string_poly, UnivList, PolyList),
string__format(FormatStr, PolyList, FinalStr).
% Convert a univ to a string_poly.
:- pred sprintf__univ_to_string_poly(univ, string__poly_type).
:- mode sprintf__univ_to_string_poly(in, out) is det.
sprintf__univ_to_string_poly(Univ, Poly) :-
( univ_to_type(Univ, Float) ->
Poly = f(Float)
; univ_to_type(Univ, Int) ->
Poly = i(Int)
; univ_to_type(Univ, String) ->
Poly = s(String)
; univ_to_type(Univ, Char) ->
Poly = c(Char)
;
error("unable to convert univ to string__poly_type")
).
--
Tyson Dowd # Another great idea from the
# people who brought you
trd at .cs.mu.oz.au # Beer Milkshakes!
http://www.cs.mu.oz.au/~trd # Confidence --- Red Dwarf
More information about the developers
mailing list