Re[4]: [Haskell] Dynamic binding

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

Interestingly this is exactly the approach taken in the OOHaskell paper! The difference is we used extensible records with subtyping (from the HList paper) to implement inheritance and overloading, which you cannot do with ordinary Haskell records. So you statment that it is better to do it in Haskell, well we are both doing it in Haskell, and your proposed method is just a simplified version of what we are doing in the paper. Keean. Bulat Ziganshin wrote:
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 :)
participants (2)
-
Bulat Ziganshin
-
Keean Schupke