
Have you read the OOHaskell paper? http://homepages.cwi.nl/~ralf/OOHaskell/ This shows how to encode many OO idioms in Haskell, without any extensions (beyond those that GHC already supports)... Here's some sample code (from the Shapes.hs example) to give you a flavor of it: A constructor function: rectangle x y width height self = do super <- shape x y self w <- newIORef width h <- newIORef height returnIO $ getWidth .=. readIORef w .*. getHeight .=. readIORef h .*. setWidth .=. (\neww -> writeIORef w neww) .*. setHeight .=. (\newh -> writeIORef h newh) .*. draw .=. do putStr "Drawing a Rectangle at:(" << self # getX << ls "," << self # getY << ls "), width " << self # getWidth << ls ", height " << self # getHeight << ls "\n" .*. super And an example of some objects in use: myShapesOOP = do -- set up array of shapes s1 <- mfix (rectangle (10::Int) (20::Int) 5 6) s2 <- mfix (circle (15::Int) 25 8) let scribble :: [Shape Int] scribble = [narrow s1, narrow s2] -- iterate through the array -- and handle shapes polymorphically mapM_ (\shape -> do shape # draw (shape # rMoveTo) 100 100 shape # draw) scribble -- call a rectangle specific function arec <- mfix (rectangle (0::Int) (0::Int) 15 15) arec # setWidth $ 30 arec # draw Regards, Keean. Marcin 'Qrczak' Kowalczyk wrote:
Haskell provides only:
- algebraic types (must specify all "subtypes" in one place), - classes (requires foralls which limits applicability: no heterogeneous lists, I guess no implicit parameters), - classes wrapped in existentials, or records of functions (these two approaches don't support controlled downcasting, i.e. "if this is a regular file, do something, otherwise do something else").