After browsing through the Standard Library Proposal for Haskell 1.3 (Version 3
from September 6, 1995), I have the following questions:
1) The proposal for collections (sec. 4.2) mentions four different
_libraries_ which all define identical functions. IMHO, this should
better be a single (contructor-) _class_ . To explain this a little
further, a small sketch of it is appendend at the end of the mail.
Implementing collections as a class would relieve the programmer from
changing a lot of type contexts if the undelying implementation of
collections is changed. The same argument holds for mappings, etc.
To make my point a little clearer, imagine the following scenario:
A program which handles collections via ListSets (requiring Eq) turns out
to be too slow. So the programmer decides to implement collections as
Sets (requiring Ord) instead. This forces changing the context (Eq a) to
(Ord a) in all places where collections are used (where a is the type of
the elements in the collection).
2) Trying to implement this constructor class (see below), I needed a
constructor class with _two_ type variables. Gofer allows this, but
Haskell 1.3 does not. Are there any serious theoretical obstacles for
insisting on a single type variable in a class declaration? If not,
including Gofer's generality in Haskell would be nice.
3) Are there ways of achieving the desired behaviour with a single type
variable in the class declaration? If so, forget my previous
question. :-)
---SNIP--SNIP--SNIP--SNIP--SNIP--SNIP--SNIP--SNIP---
\begin{code}
-- Collections as a constructor class
module Collections (Collection, UList, SList) where
-- Not standard Haskell 1.3, but Gofer-conformant
class Collection col a where
empty :: col a
singleton ::a - col a
add :: a - col a - col a
delete:: (Eq a) = a - col a - col a
singleton x = add x empty
-- a collection as an unsorted list without duplicates
data UList a = UList [a]
instance (Eq a) = Collection UList a where
empty = UList []
add e u@(UList l) | any (e ==) l = u
| otherwise= UList (e:l)
delete e (UList l) = UList (del l)
where del [] = []
del (x:xs) | e == x= xs
| otherwise = x:(del xs)
-- a collection as a sorted list without duplicates
data SList a = SList [a]
instance (Ord a) = Collection SList a where
empty = SList []
add e (SList l) = SList (adjoin l)
where adjoin [] = [e]
adjoin ys@(x:xs) | e x = e:ys
| e == x = ys
| e x = x:(adjoin xs)
delete e (SList l) = SList (del l)
where del [] = []
del ys@(x:xs) | e x = ys
| e == x = xs
| e x = x:(del xs)
-- a collection as an unbalanced binary tree
--
-- data Tree a = Empty | Node a (Tree a) (Tree a)
--
-- instance (Ord a) = Collection Tree a where ...
--
-- and so on...
\end{code}
\begin{code}
-- And now to something completely different... ;-)
-- A module which uses the above Collection class
-- Note: All but the last type declarations are superfluous.
module Test where
import Collections
foo :: Collection col Char = col Char - col Char
foo c = add 'a' c
bar :: (Collection col a, Eq a) = col a - a - col a
bar c x = delete x c
baz :: Collection a Char = a Char - a Char
baz c = bar c 'a'
addRange :: (Enum a, Collection col a) = a - a - col a - col a
addRange start end c = foldr add c [start..end]
test :: SList Char
test = addRange 'a' 'z' empty
\end{code}
---SNIP--SNIP--SNIP--SNIP--SNIP--SNIP--SNIP--SNIP---
--
Sven Panne Tel.: +49/89/21106-90
LMU, Institut fuer Informatik FAX : +49/89/21106-99
LFE Programmier- und Modellierungssprachen Wagmuellerstr. 23
mailto:[EMAIL PROTECTED]D-80538 Muenchen