{-# OPTIONS -fglasgow-exts #-} {-# OPTIONS -fallow-undecidable-instances #-} {-# OPTIONS -fallow-overlapping-instances #-} {- -- (C) 2004-2005, Oleg Kiselyov & Ralf Laemmel -- Haskell's overlooked object system A variation on the shapes example. We make shapes opaque in an existential envelope. Thereby, all shapes can be inserted into a normal homogeneous list. -} module ShapesExists where import OOHaskell import Shapes -- The polymorphic scribble loop. main = do -- set up list of shapes. s1 <- mfix (rectangle (10::Int) (20::Int) (5::Int) (6::Int)) s2 <- mfix (circle (15::Int) (25::Int) (8::Int)) let scribble = [ HideShape s1 , HideShape s2 ] -- iterate through the list -- and handle shapes polymorphically mapM_ ( \(HideShape shape) -> do shape # draw (shape # rMoveTo) 100 100 shape # draw ) scribble -- call a rectangle specific function arec <- mfix (rectangle (0::Int) (0::Int) (15::Int) (15::Int)) arec # setWidth $ 30 arec # draw -- The well-quantified existential wrapper data OpaqueShape = forall x. ( HasField (Proxy Draw) x (IO ()) , HasField (Proxy RMoveTo) x (Int -> Int -> IO ()) ) => HideShape x