
Hello Ralf, Thursday, June 23, 2005, 11:36:20 AM, you wrote:
just create list of draw functions itself:
[drawCircle (10,10) 5, drawSquare (20,20) 10]
RL> No! the exercise is about lists of shapes RL> not lists of results of drawing shapes. RL> This is clearly a major difference. in cases where you need to call only one function on created objects, you can just insert in list calls to this functions (not their results! i suppose that drawXXX functions has "... -> IO ()" type) in cases where you need to call several functions for this object, you can insert in list tuple or structure for each object, as i do in next example. original exercise was about OO way to solve some problem. i want to say that in Haskell it's better in most cases to use another, functional way RL> Bulat wrote:
for more complex tasks - declare interface as a structure:
data ShapeInterface = Shape { draw :: IO (), moveTo :: Point -> IO (), calcArea :: Float }
RL> No! You miss the point that the different shapes RL> differ regarding state types. RL> You don't have a chance when you use one datatype. this state is just don't need to appear in interface definition :) see for example: data ShapeInterface = Shape { draw :: IO (), calcArea :: Float } circle x y r = Shape { draw = drawCircle x y r, calcArea = pi*r*r } square x y size = Shape { draw = drawSquare x y size, calcArea = size*szie } figures = [circle 1 2 3, square 4 5 6, circle 7 8 9] if you need to maintain mutable state, this is also not a problem: data ShapeInterface = Shape { draw :: IO (), moveTo :: (Int,Int) -> IO (), calcArea :: Float } circle x y r = do center <- ref (x,y) return Shape { draw = val center >>= drawCircle r , moveTo = (center=:) , calcArea = pi*r*r } main = do figures <- sequence [circle 1 2 3, square 4 5 6, circle 7 8 9] mapM_ draw figures mapM_ (moveTo (0,0)) figures mapM_ draw figures ref=newIORef val=readIORef (=:)=writeIORef RL> haskell-cafe? as you wish :) -- Best regards, Bulat mailto:bulatz@HotPOP.com