Picking out elements of a heterogenous list

Hi Haskell-ers, So I think I understand the idea of creating a heterogenous list using typeclasses and existentials, but I don't see how to filter the list to retrieve elements of the list that are of only one type. More concretely, taking the example herehttp://haskell.org/haskellwiki/Existential_typehow could we take a list of shapes [Shape] and pull out all objects that are Squares? I don't see an obvious way this makes sense. Is there a way of doing heterogenous lists that would make this possible?

To: "Creighton Hogg"
Hi Haskell-ers, So I think I understand the idea of creating a heterogenous list using typeclasses and existentials, but I don't see how to filter the list to retrieve elements of the list that are of only one type.
More concretely, taking the example herehttp://haskell.org/haskellwiki/Existential_typehow could we take a list of shapes [Shape] and pull out all objects that are Squares? I don't see an obvious way this makes sense. Is there a way of doing heterogenous lists that would make this possible?
Use filter, passing it a predicate that returns True for Squares and False otherwise: isASquare :: Shape -> Bool isASquare (Square _) = True isASquare _ = False filter isASquare myShapes Steve Schafer Fenestra Technologies Corp. http://www.fenestra.com/

On Tue, Dec 05, 2006 at 11:08:07AM -0600, Creighton Hogg wrote:
Hi Haskell-ers, So I think I understand the idea of creating a heterogenous list using typeclasses and existentials, but I don't see how to filter the list to retrieve elements of the list that are of only one type.
More concretely, taking the example herehttp://haskell.org/haskellwiki/Existential_typehow could we take a list of shapes [Shape] and pull out all objects that are Squares? I don't see an obvious way this makes sense. Is there a way of doing heterogenous lists that would make this possible?
It's ugly but you could stick converters in the class itself: class MyClass a where isTypeA :: a -> Maybe A isTypeA _ = Nothing isTypeB :: a -> Maybe B isTypeB _ = Nothing isTypeC :: a -> Maybe C isTypeC _ = Nothing This limits you to a finite number of specific types, but I suspect that's unavoidable. Actually, your list can have any number of types in it, but you can only extract a fixed set of types. Another perhaps prettier way to do this would be to use an ADT to hold the elements of your list, so that the existentials could be reconstructed by pattern matching: data FunnyElement = ElemA A | ElemB B | ElemC C Again, it only works for lists containing a fixed set of types. -- David Roundy Department of Physics Oregon State University

I generally use the Typeable class for this. In that example, you'd want:
class Typeable a => Shape_ a
instead of just
class Shape_ a
and then your filter predicate would look like:
isSquare :: Shape -> Bool
isSquare (Shape s) = typeOf s == typeOf square
where square :: Square ; square = undefined
(warning: I didn't try this code.)
That adds a little overhead (particularly in that everything must now
derive Typeable) but is one of the better solutions I've seen.
/g
On 12/5/06, Creighton Hogg
Hi Haskell-ers, So I think I understand the idea of creating a heterogenous list using typeclasses and existentials, but I don't see how to filter the list to retrieve elements of the list that are of only one type.
More concretely, taking the example here how could we take a list of shapes [Shape] and pull out all objects that are Squares? I don't see an obvious way this makes sense. Is there a way of doing heterogenous lists that would make this possible?
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- It is myself I have never met, whose face is pasted on the underside of my mind.
participants (4)
-
Creighton Hogg
-
David Roundy
-
J. Garrett Morris
-
Steve Schafer