Roly Perera | 7 Oct 14:11

Type classes question

Hi,

I'm reasonably well versed in Haskell but fairly new to defining type classes.  
In particular I don't really understand how to arrange for all instances of X 
to also be instances of Y.  

It's quite possibly that my question is ill-posed, so I'll make it as concrete 
as possible: in the following code, I define a Stream class, with two 
instances, Stream1 and Stream2.  How do I arrange for there to be one 
implementation of Functor's fmap for all Stream instances?  I currently rely on 
delegation, but in the general case this isn't nice.

I guess I'm either misunderstanding what it is I'm trying to achieve, or how to 
do this kind of thing in Haskell.  Any help would be greatly appreciated.

many thanks,
Roly Perera

{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, 
ExistentialQuantification, FunctionalDependencies #-}

module Test where

-------------------------------------------------------------------------------
-- Just some helpers.
-------------------------------------------------------------------------------

-- Product map.
prod :: (a -> b) -> (c -> d) -> (a, c) -> (b, d)
f `prod` g = \(a, c) -> (f a, g c)
(Continue reading)

Ryan Ingram | 7 Oct 15:21

Re: Type classes question

On Tue, Oct 7, 2008 at 1:13 PM, Roly Perera
<roly.perera <at> dynamicaspects.org> wrote:
> Hi,
>
> I'm reasonably well versed in Haskell but fairly new to defining type classes.
> In particular I don't really understand how to arrange for all instances of X
> to also be instances of Y.
>
> It's quite possibly that my question is ill-posed, so I'll make it as concrete
> as possible: in the following code, I define a Stream class, with two
> instances, Stream1 and Stream2.  How do I arrange for there to be one
> implementation of Functor's fmap for all Stream instances?  I currently rely on
> delegation, but in the general case this isn't nice.

With your current implementation, you can't.  You get lucky because
all of your instance declarations are of the form
> instance Stream (X a) a
for some type X.

But it's just as possible to say

> newtype Stream3 = S3 [Int]

> instance Stream Stream3 Int where
>   first (S3 xs) = head xs
>   next (S3 xs) = tail xs
>   fby x (S3 xs) = S3 (x:xs)

Now the only valid fmap_ is over functions of type (Int -> Int).

(Continue reading)

Roly Perera | 8 Oct 13:22

Re: Type classes question

Ryan Ingram <ryani.spam <at> gmail.com> writes:

> [...]
> 
> Here's another possible solution:
> 
> > newtype AsFunctor s a = AF { fstream :: (s a) }
> > instance (Stream f) => Functor (AsFunctor f) where
> >     fmap f (AF s) = AF (fmapStreamDefault f s)
> 
> Now to use fmap you wrap in AF and unwrap with fstream.
> 
> None of the existing solutions are really satisfactory, unfortunately.

Bulat Ziganshin <bulat.ziganshin <at> gmail.com> writes:

> http://haskell.org/haskellwiki/OOP_vs_type_classes may be useful

Many thanks to you both for the clarification and pointers.

cheers,
Roly
Bulat Ziganshin | 7 Oct 17:48

Re: Type classes question

Hello Roly,

Tuesday, October 7, 2008, 4:13:25 PM, you wrote:

> I'm reasonably well versed in Haskell but fairly new to defining type classes.

http://haskell.org/haskellwiki/OOP_vs_type_classes may be useful

--

-- 
Best regards,
 Bulat                            mailto:Bulat.Ziganshin <at> gmail.com

Gmane