Re[2]: [Haskell-cafe] OO Design in Haskell Example (Draft)

2007-02-26 Thread Bulat Ziganshin
Hello Tim,

Monday, February 26, 2007, 2:26:44 AM, you wrote:

 Rather than using existential types, a simple record of
 functions can be often be useful. ie:

 data Component = Component {
 draw :: String
 add  :: Component - Component
 }

Steve, you can look at the pages
http://haskell.org/haskellwiki/OOP_vs_type_classes
http://haskell.org/haskellwiki/IO_inside
which describes some alternatives to OO approach used in functional
programming world and Haskell in partial. because first page is just
about switching from OOP to Haskell, you may consider adding to this
page patterns you've designed

-- 
Best regards,
 Bulatmailto:[EMAIL PROTECTED]

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] OO Design in Haskell Example (Draft)

2007-02-26 Thread oleg

Steve Downey wrote:
 In the last OO design in Haskell thread (and probably in every one
 preceeding it), it was suggested that having some examples might be a good
 idea.

 Since most people with existing designs will have some familiarity with
 Design Patterns, and those are typical building blocks for OO designs, it
 occured to me that implementing some of them might be a useful
 excersize.

Have you looked at OOHaskell?
http://homepages.cwi.nl/~ralf/OOHaskell/
http://darcs.haskell.org/OOHaskell/

With the exception of pure-functional objects and binary methods, I
think we have considered almost every OO pattern/idiom we could find,
including nominal/structural subtyping, co- and contra-variance,
self-typing, etc. The DARCS repository contains the complete code for
all of the examples and patterns. To clarify, the point of OOHaskell
is to use Haskell as a tool, laboratory bench, for exploring various
(thorny) OO issues.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] OO Design in Haskell Example (Draft)

2007-02-25 Thread Steve Downey

In the last OO design in Haskell thread (and probably in every one
preceeding it), it was suggested that having some examples might be a good
idea.

Since most people with existing designs will have some familiarity with
Design Patterns, and those are typical building blocks for OO designs, it
occured to me that implementing some of them might be a useful excersize. If
for nothing other than learning some more Haskell.

Now, some of them are probably bad ideas for implementing in Haskell.
There's a better, or more natural, way than what is suggested by the design
pattern. Visitor is probably not a good pattern to follow, for example. On
the other hand, others may still be useful, even in a functional language.

So, I've been working on a Composite example. I've used existential types to
have a generic proxy to the base type, rather than a simple algebraic type,
since adding new leaves to the algebraic type means modifying the whole
type, a violation of the Open-Closed principle (open for extension, closed
for modification)

The interface of the composite. Two methods, add and draw.


class IComponent e where
draw ::e - String
add :: (IComponent e') = e - e' - Component



A proxy type which can hold any kind of component, and provides the
'virtual' dispatch implementation. That is, it forwards to the add
or draw implementation of the instance it is proxying for.


data Component =
forall e.(IComponent e) = Component e



componentDraw :: Component - String
componentDraw (Component c) = draw c



componentAdd :: (IComponent e) = Component - e - Component
componentAdd (Component e) a  = Component (add e a)



instance IComponent Component where
draw = componentDraw
add = componentAdd



The Single type, which is the leaf node in this composite, add is a
no-op, except for wrapping the value in a Component. Since there
isn't an implicit down cast from the 'derived' Single to the 'base'
Component.


data Leaf =
Text String
deriving(Show, Eq)



leafDraw :: Leaf - String
leafDraw (Text s) = show s



leafAdd :: (IComponent e) = Leaf - e - Component
leafAdd s _  = Component s



instance IComponent Leaf where
draw = leafDraw
add = leafAdd




The Composite type, which holds a list of Components through the
composite proxy. I was tempted to make the list a state variable,
so that add could modify rather than produce a new Many, but I
wanted to get the basics working.


data Composite =
Many [Component]



compositeDraw :: Composite - String
compositeDraw (Many [])  = ()
compositeDraw (Many leaves)  = ( ++ (foldr1 (++) $ map draw leaves) ++

)


compositeAdd :: (IComponent e) = Composite - e - Component
compositeAdd (Many leaves) c =
Component $ Many ((Component c) : leaves)



instance IComponent Composite where
draw = compositeDraw
add = compositeAdd

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


RE: [Haskell-cafe] OO Design in Haskell Example (Draft)

2007-02-25 Thread Tim Docker
Steve Downey wrote: 
  So, I've been working on a Composite example. I've used
  existential types to have a generic proxy to the base
  type, rather than a simple algebraic type, since adding
  new leaves to the algebraic type means modifying the whole
  type, a violation of the Open-Closed principle (open for
  extension, closed for modification)

Rather than using existential types, a simple record of
functions can be often be useful. ie:

data Component = Component {
draw :: String
add  :: Component - Component
}

It might be worth comparing this approach with the (more
complex) one you have described.

Tim
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe