forall quantifier

Tom Pledger Tom.Pledger@peace.com
Thu, 5 Jun 2003 08:25:08 +1200


Ketil Z. Malde writes:
 :
 |   classify :: Eq b =3D> [a->b] -> [a] -> [[[a]]]
 |   classify cs xs =3D ...
 |=20
 | where for each classifying function in cs, I would get the xs
 | partitioned accordingly.  E.g.
 |=20
 |   classify [fst,snd] [(1,0), (1,2), (2,0)]=20
 |=20
 | would yield
 |=20
 |   [ [(1,0), (1,2)], [(2,0)] -- classified by `fst`
 |   , [(1,0), (2,0)], [(1,2)]] -- classified by `snd`
 |=20
 | Now, obviously, the problem is that fst and snd, being passed in a
 | list, needs to be of the same type; this complicates classifying a
 | list of type [(Int,Bool)], for instance=B9.
 :
 | Can somebody suggest a solution, or a place to look?

Hi.

Another way is to extend the role of the classifying functions, so
that they go on to make the comparison after extracting the
classification keys.  Here's a naive implementation.

> import Data.List(partition)
>=20
> classifyBy :: (a -> a -> Bool) -> [a] -> [[a]]
> classifyBy eq [] =3D []
> classifyBy eq (x:xs) =3D case partition (eq x) xs of
>                            (ys, zs) -> (x:ys):classifyBy eq zs
>=20
> classifyBys :: [a -> a -> Bool] -> [a] -> [[[a]]]
> classifyBys eqs xs =3D [classifyBy eq xs | eq <- eqs]
>=20
> fsteq x y =3D fst x =3D=3D fst y
> sndeq x y =3D snd x =3D=3D snd y
>=20
> test =3D classifyBys [fsteq, sndeq] [(1, '0'), (1, '2'), (2, '0')]

In practice, you'd probably want an Ord-like comparison (a -> a ->
Ordering) instead of the Eq-like one (a -> a -> Bool).

Regards,
Tom 'existential quantifier skeptic' ;-)