Serge D. Mechveliani wrote:
> 
> I am sorry, may I ask, again, a question about categories and standard 
> constructors?
> This time it is more concrete.
> Concerning my request on adding categories to standard constructors
> Waldek wrote 
> 
> > Why do you need Integer (etc.) to have ParseCategory?  You can have:
> >
> > ParseCategory(T : SetCategory) : Category ==  SetCategory with
> >   parseElem : String -> Product(T, String)
> > [..]
> >
> > and then implement packages of that category.
> 
> 2. Here is a concrete and small contrived example/question presented by
>    an Haskell program.
> 

OK, so you really do not care about adding category to Integer,
what you really want is to define a function, recursively
combining pieces defined for various types.  In other
words we have your old problem of dispatching on types.

Now, adding your function to Integer, ..., etc. solves dispactching
problem by using normal Spad dispatching.  Still, for me it does
not look like "right" solution: currently Integer has 107
operations.  If each user could at will add operations to Integer
we may easily get hundreds or thousends of operations in
Integer with risk of name clashes etc.

Now, I admit that if you insist on your interface, that is
all you have is just a type (which is build from limited
set of constructors but allows arbitrary composition), then
Spad does not offer solution to you problem (as opposed
to workarounds).

OTOH, when we look at your real problem (that is of creating
Haskell interface), than I feel that there is quite
satisfactory solution.  Namely, you start from a string
describing type.  Parsing this string you create type
and a package containg appropriate function(s): a
function to parse strings to the type and a function to
unparse elements of the type to stings.  Concretely, you have:

UnparserCategory(T : Type) : Category == with (show : T -> Sting)

SparseUnivariatePolynomialUnparser(R : Ring, UR : UnparserCategory(R)) : _
  UnparserCategory(SparseUnivariatePolynomial(R))
 == add
    show(x) ==
       x = 0 => "([], [])"
       dl := List(NonNegativeInteger) :=  reverse(map(degree, monomials(p)))
       cl := List(String) := reverse(map(show$UR, coefficients(p)))
       s1 : String := toString(first(dl))
       s2 := frist(cl)
       for i in rest(dl) for c in cl repeat
           s1 := concat(toString(i), concat(", "), s1)
           s2 := concat(c, concat(", "), s2)
       concat(["([", s1, "], [", s2, "])"])

Note: I assumed that there is a function to convert integers to
strings.  ATM one has to do something like

   toString(i : Integer) : String == FORMAT(nil, "~d", i)$Lisp

or

   toString(i : Integer) : String == unparse(i::InputForm)$InputForm


Case of Product is easier:

ProductUnparser(A : SetCategory, B : SetCategory,
                UA : UnparserCategory(A), UB : UnparserCategory(B)) _
               : UnparserCategory(Product(A, B))
 == add

   show(x) ==
       concat("[", concat(show(first(x))$UA, concat(", ", _
          concat(show(second(x)$UB, "]")))))


Alternatively, you can have 'make_show' function and pass
unparsers of parameters of type as parameters to 'make_show'.
If you need a single function (or a few loosely connected
functions), then I would probably use 'make_show' version.
If there are more related functions than passing package
as type parameter looks more attractive than passing several
functions.

Note: In principle one could pass a package as parameter to
'make_show'.  However calling functions from such package
is less efficient than other function calls, so the two
alternatives I gave are faster.

-- 
                              Waldek Hebisch
[email protected] 

-- 
You received this message because you are subscribed to the Google Groups 
"FriCAS - computer algebra system" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/fricas-devel?hl=en.

Reply via email to