Send Beginners mailing list submissions to
[email protected]
To subscribe or unsubscribe via the World Wide Web, visit
http://www.haskell.org/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
[email protected]
You can reach the person managing the list at
[email protected]
When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."
Today's Topics:
1. Encapsulation and Polymorphism (Drew Haven)
2. Re: Encapsulation and Polymorphism (Drew Haven)
3. Re: Re: Encapsulation and Polymorphism (Stephen Tetley)
4. Re: Re: Encapsulation and Polymorphism (Alex Rozenshteyn)
5. Re: Re: Encapsulation and Polymorphism (Ozgur Akgun)
6. Re: Re: Encapsulation and Polymorphism (Stephen Tetley)
----------------------------------------------------------------------
Message: 1
Date: Wed, 25 Aug 2010 21:43:51 -0700
From: Drew Haven <[email protected]>
Subject: [Haskell-beginners] Encapsulation and Polymorphism
To: [email protected]
Message-ID:
<[email protected]>
Content-Type: text/plain; charset=ISO-8859-1
I thought I was getting pretty good at Haskell, until I ran into this
problem. It's basically a way of maintaining encapsulation of data
and functions while being able to have a container, such as a list,
hold these items without worrying about their differences. In OO this
would be pretty easy. You'd have an interface of some sort and the
container would hold objects of the interface type. Then you could
write the individual classes that implement that interface in their
own files and the main program wouldn't have to know about the
details.
I'm trying to write a silly little life simulator. We've got a world
where many different entities exist. These entities are all
different, but for a start we'll use fish and shark. The fish like to
swim around in the sea, and will manage to eat some amount of the
overall food supply. The amount they consume from year to year varies
and they have to consume a minimum amount every year or they die.
When they've eaten enough food and have build up a surplus, they'll
reproduce, but if they're starving they can't. Sharks are similar,
except their food supply is the fish. The two are very similar, but
do slightly different things. And every fish or shark has to keep
track of its own amount of consumed food.
If I wanted to define these separately, the best I've come up with is
to create a data type that has all the information necessary, then
somewhere maintain a master algebraic data type which wraps each of
these in a type constructor. I can then write another head for a
general function that will match that type constructor and describe
the behavior.
I tried something clever with closures, but it turned out to be too
clever for me and I couldn't avoid infinite types.
Thoughts?
Drew Haven
[email protected]
------------------------------
Message: 2
Date: Wed, 25 Aug 2010 23:45:12 -0700
From: Drew Haven <[email protected]>
Subject: [Haskell-beginners] Re: Encapsulation and Polymorphism
To: [email protected]
Message-ID:
<[email protected]>
Content-Type: text/plain; charset=ISO-8859-1
I think I found the answers to all my questions at
http://www.haskell.org/haskellwiki/Existential_type
Drew Haven
[email protected]
On Wed, Aug 25, 2010 at 9:43 PM, Drew Haven <[email protected]> wrote:
> I thought I was getting pretty good at Haskell, until I ran into this
> problem. It's basically a way of maintaining encapsulation of data
> and functions while being able to have a container, such as a list,
> hold these items without worrying about their differences. In OO this
> would be pretty easy. You'd have an interface of some sort and the
> container would hold objects of the interface type. Then you could
> write the individual classes that implement that interface in their
> own files and the main program wouldn't have to know about the
> details.
>
> I'm trying to write a silly little life simulator. We've got a world
> where many different entities exist. These entities are all
> different, but for a start we'll use fish and shark. The fish like to
> swim around in the sea, and will manage to eat some amount of the
> overall food supply. The amount they consume from year to year varies
> and they have to consume a minimum amount every year or they die.
> When they've eaten enough food and have build up a surplus, they'll
> reproduce, but if they're starving they can't. Sharks are similar,
> except their food supply is the fish. The two are very similar, but
> do slightly different things. And every fish or shark has to keep
> track of its own amount of consumed food.
>
> If I wanted to define these separately, the best I've come up with is
> to create a data type that has all the information necessary, then
> somewhere maintain a master algebraic data type which wraps each of
> these in a type constructor. I can then write another head for a
> general function that will match that type constructor and describe
> the behavior.
>
> I tried something clever with closures, but it turned out to be too
> clever for me and I couldn't avoid infinite types.
>
> Thoughts?
>
> Drew Haven
> [email protected]
>
------------------------------
Message: 3
Date: Thu, 26 Aug 2010 08:08:48 +0100
From: Stephen Tetley <[email protected]>
Subject: Re: [Haskell-beginners] Re: Encapsulation and Polymorphism
Cc: [email protected]
Message-ID:
<[email protected]>
Content-Type: text/plain; charset=ISO-8859-1
Hi Drew
Bear in mind though that existentials are not equivalent to subtyping in OO.
For instance, with example 2.1 from [1] all you can do with an Obj is
show it, so for the list xs all you can do is show the elements:
data Obj = forall a. (Show a) => Obj a
xs :: [Obj]
xs = [Obj 1, Obj "foo", Obj 'c']
Because Obj is an existential you can't do an case analysis on it - so
you can't write a function like this:
add_one_if_int (Obj (n::Int)) = Obj (n+1)
add_one_if_int (Obj other) = Obj other
There really is nothing you can do with Obj other than show it.
If you are trying to transliterate OO designs, you might quickly find
existentials are too inert to be useful.
Best wishes
Stephen
[1] http://www.haskell.org/haskellwiki/Existential_type
On 26 August 2010 07:45, Drew Haven <[email protected]> wrote:
> I think I found the answers to all my questions at
> http://www.haskell.org/haskellwiki/Existential_type
------------------------------
Message: 4
Date: Thu, 26 Aug 2010 13:50:49 +0300
From: Alex Rozenshteyn <[email protected]>
Subject: Re: [Haskell-beginners] Re: Encapsulation and Polymorphism
To: Stephen Tetley <[email protected]>
Cc: [email protected]
Message-ID:
<[email protected]>
Content-Type: text/plain; charset="utf-8"
>From what I understand (not much), It seems that type-classes are
more-or-less equivalent to OO interfaces (I think OP mentioned this), and
that containers with existential types are less more-or-less equivalent to
OO containers whose elements implement an interface, the biggest exception
being that you can't use anything that isn't a part of the class on the
contained values.
As I understand, something like this could be relevant:
> class AquaticLifeform a where
> nutrition :: Int
> reproduce :: Maybe (a, a)
On Thu, Aug 26, 2010 at 10:08 AM, Stephen Tetley
<[email protected]>wrote:
> Hi Drew
>
> Bear in mind though that existentials are not equivalent to subtyping in
> OO.
>
> For instance, with example 2.1 from [1] all you can do with an Obj is
> show it, so for the list xs all you can do is show the elements:
>
> data Obj = forall a. (Show a) => Obj a
>
> xs :: [Obj]
> xs = [Obj 1, Obj "foo", Obj 'c']
>
> Because Obj is an existential you can't do an case analysis on it - so
> you can't write a function like this:
>
> add_one_if_int (Obj (n::Int)) = Obj (n+1)
> add_one_if_int (Obj other) = Obj other
>
> There really is nothing you can do with Obj other than show it.
>
>
> If you are trying to transliterate OO designs, you might quickly find
> existentials are too inert to be useful.
>
> Best wishes
>
> Stephen
>
> [1] http://www.haskell.org/haskellwiki/Existential_type
>
>
> On 26 August 2010 07:45, Drew Haven <[email protected]> wrote:
> > I think I found the answers to all my questions at
> > http://www.haskell.org/haskellwiki/Existential_type
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://www.haskell.org/mailman/listinfo/beginners
>
--
Alex R
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
http://www.haskell.org/pipermail/beginners/attachments/20100826/94bfb9f3/attachment-0001.html
------------------------------
Message: 5
Date: Thu, 26 Aug 2010 11:51:55 +0100
From: Ozgur Akgun <[email protected]>
Subject: Re: [Haskell-beginners] Re: Encapsulation and Polymorphism
To: Stephen Tetley <[email protected]>
Cc: [email protected]
Message-ID:
<[email protected]>
Content-Type: text/plain; charset="utf-8"
On 26 August 2010 08:08, Stephen Tetley <[email protected]> wrote:
> Hi Drew
>
> Bear in mind though that existentials are not equivalent to subtyping in
> OO.
>
> For instance, with example 2.1 from [1] all you can do with an Obj is
> show it, so for the list xs all you can do is show the elements:
>
> data Obj = forall a. (Show a) => Obj a
>
> xs :: [Obj]
> xs = [Obj 1, Obj "foo", Obj 'c']
>
> Because Obj is an existential you can't do an case analysis on it - so
> you can't write a function like this:
>
> add_one_if_int (Obj (n::Int)) = Obj (n+1)
> add_one_if_int (Obj other) = Obj other
>
> There really is nothing you can do with Obj other than show it.
>
But that's because you use Show while defining the Obj data type. You can
implement other functionalities, by introducing a custom type class, and
implementing functionalities in instance declarations.
class Show a => CustomTC a where
add_one_if_int :: a -> a
instance CustomTC Int where
add_one_if_int x = x + 1
instance CustomTC Char where
add_one_if_int = id
instance CustomTC String where
add_one_if_int = id
xs :: [Obj]
xs = [Obj (1 :: Int), Obj "foo", Obj 'c']
xs' :: [Obj]
xs' = map (\ (Obj i) -> Obj (add_one_if_int i) ) xs
-- xs' = [Obj 2,Obj "foo",Obj 'c']
If you are trying to transliterate OO designs, you might quickly find
> existentials are too inert to be useful.
>
> Best wishes
>
> Stephen
>
> [1] http://www.haskell.org/haskellwiki/Existential_type
>
>
> On 26 August 2010 07:45, Drew Haven <[email protected]> wrote:
> > I think I found the answers to all my questions at
> > http://www.haskell.org/haskellwiki/Existential_type
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://www.haskell.org/mailman/listinfo/beginners
>
--
Ozgur Akgun
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
http://www.haskell.org/pipermail/beginners/attachments/20100826/1f26f92b/attachment-0001.html
------------------------------
Message: 6
Date: Thu, 26 Aug 2010 13:16:13 +0100
From: Stephen Tetley <[email protected]>
Subject: Re: [Haskell-beginners] Re: Encapsulation and Polymorphism
Cc: [email protected]
Message-ID:
<[email protected]>
Content-Type: text/plain; charset=ISO-8859-1
On 26 August 2010 11:51, Ozgur Akgun <[email protected]> wrote:
[SNIP]
>
> But that's because you use Show while defining the Obj data type. You can
> implement other functionalities, by introducing a custom type class, and
> implementing functionalities in instance declarations.
>
Hi Ozgur
This is well known, of course, Ralf Lammel (umlauts on the a in
Lammel) and Klaus Ostermann have a catalogue of "shoehorns" to fit OO
design into Haskell:
http://homepages.cwi.nl/~ralf/gpce06/paper.pdf
However these styles aren't exemplary [*] - little Haskell code that
I've seen in the wild makes use of them. For instance, having a type
class for each operation as per CustomTC seems exorbitant, likewise
adding type class contexts to datatype definitions quickly becomes
unwieldy:
data Obj = forall a. (Show a, AquaticLifeform a, ...) => Obj a
Best wishes
Stephen
[*] Caveat - Figure 16 is quite reminiscent of the "finally tagless"
style which is now widely used.
------------------------------
_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners
End of Beginners Digest, Vol 26, Issue 50
*****************************************