Send Beginners mailing list submissions to
        beginners@haskell.org

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
        beginners-requ...@haskell.org

You can reach the person managing the list at
        beginners-ow...@haskell.org

When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."


Today's Topics:

   1. Re:  (Implicit) equality testing using multiple function
      definitions (Tom Murphy)
   2. Re:  (Implicit) equality testing using multiple function
      definitions (Brandon Allbery)
   3. Re:  (Implicit) equality testing using multiple function
      definitions (Brent Yorgey)
   4.  Typeclasses vs. Data (Thomas)
   5. Re:  Typeclasses vs. Data (David Place)
   6. Re:  Typeclasses vs. Data (David Place)
   7. Re:  Typeclasses vs. Data (Thomas)
   8. Re:  Typeclasses vs. Data (David Place)


----------------------------------------------------------------------

Message: 1
Date: Wed, 20 Jul 2011 14:38:39 -0400
From: Tom Murphy <amin...@gmail.com>
Subject: Re: [Haskell-beginners] (Implicit) equality testing using
        multiple function definitions
To: Brandon Allbery <allber...@gmail.com>
Cc: beginners <beginners@haskell.org>
Message-ID:
        <CAO9Q0tV90qUJM1uAKazByh8jRuTTum3=kx8p+dyzku40sm2...@mail.gmail.com>
Content-Type: text/plain; charset=ISO-8859-1

On 7/18/11, Brandon Allbery <allber...@gmail.com> wrote:
[...]
>
> "Circumvents"?  You make it sound like the point of typeclasses is to
> restrict things.  In fact, the point is to *undo* the restrictions
> necessarily introduced by polymorphism:  if you don't know the type of
> something, you don't know what you can do with it.  Typeclasses let us say
> "this can be any type, but we need to be able to do <x> with it".  They
> don't circumvent; they *add*.
>

     I wish I could think of a good example. Since I can't, I'll just
try and make my point: In a way, the point of typeclasses _is_ to
restrict things: one of the things that typeclasses enables is a
compile-time error if I, say, try and add Bools: by not giving Bool a
Num instance, we're expressing that something can't be expressed.

     There has to be a reason why we've all typed "deriving (Eq)"
again and again: because sometimes we don't want, for some OurType, to
be able to express:
     (a :: OurType) == (b :: OurType).

     This is the source of my confusion.

Thanks for your time,
Tom



------------------------------

Message: 2
Date: Wed, 20 Jul 2011 15:05:07 -0400
From: Brandon Allbery <allber...@gmail.com>
Subject: Re: [Haskell-beginners] (Implicit) equality testing using
        multiple function definitions
To: Tom Murphy <amin...@gmail.com>
Cc: beginners <beginners@haskell.org>
Message-ID:
        <cakfcl4v4o5pornjwrem97i0cmy+qk6x989s0_sro7w47sop...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"

On Wed, Jul 20, 2011 at 14:38, Tom Murphy <amin...@gmail.com> wrote:

>     There has to be a reason why we've all typed "deriving (Eq)"
> again and again: because sometimes we don't want, for some OurType, to
> be able to express:
>     (a :: OurType) == (b :: OurType).
>

There is a good reason, but that's not it.  You're still thinking in terms
of objects that carry method dictionaries around; Haskell *is not object
oriented*, values are just values.  Operations are defined by types, not by
values.  You can't ask a value how it should be compared.

Typeclasses, which superficially look like objects/classes but aren't, are a
way around this.  A typeclass actually defines a dictionary mapping types to
functions; but because values are not objects, some way needs to be provided
to pass these dictionaries where they are needed.  This is the function of
contexts:  they're actually function arguments.

> f :: Eq a => a -> a -> a

is a function that takes three arguments:  a map of implementations, and two
values of some type.  Whenever this function is invoked, the compiler passes
it the Eq dictionary entry for the appropriate type a.  If there were
multiple typeclass contexts, the map would combine all of them.

It's not about hiding anything.  The only reason you think there is
something to hide is because an object would carry around that information
and something would therefore have to hide it for it to not be available;
but there are no objects here, so something has to be added to carry it
around.

-- 
brandon s allbery                                      allber...@gmail.com
wandering unix systems administrator (available)     (412) 475-9364 vm/sms
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
<http://www.haskell.org/pipermail/beginners/attachments/20110720/4538663d/attachment-0001.htm>

------------------------------

Message: 3
Date: Wed, 20 Jul 2011 17:04:22 -0400
From: Brent Yorgey <byor...@seas.upenn.edu>
Subject: Re: [Haskell-beginners] (Implicit) equality testing using
        multiple function definitions
To: beginners@haskell.org
Message-ID: <20110720210422.ga5...@seas.upenn.edu>
Content-Type: text/plain; charset=us-ascii

On Wed, Jul 20, 2011 at 02:38:39PM -0400, Tom Murphy wrote:
> On 7/18/11, Brandon Allbery <allber...@gmail.com> wrote:
> [...]
> >
> > "Circumvents"?  You make it sound like the point of typeclasses is to
> > restrict things.  In fact, the point is to *undo* the restrictions
> > necessarily introduced by polymorphism:  if you don't know the type of
> > something, you don't know what you can do with it.  Typeclasses let us say
> > "this can be any type, but we need to be able to do <x> with it".  They
> > don't circumvent; they *add*.
> >
> 
>      I wish I could think of a good example. Since I can't, I'll just
> try and make my point: In a way, the point of typeclasses _is_ to
> restrict things: one of the things that typeclasses enables is a
> compile-time error if I, say, try and add Bools: by not giving Bool a
> Num instance, we're expressing that something can't be expressed.

I think you are both right.  There's a duality here, depending on your
point of view.  Consider a function type

  blah :: Foo a => ... a ...

>From the point of view of someone *calling* this function, the Foo
constraint *adds* some restriction: you may only pass things whose type
is an instance of Foo.  If you try to pass anything else you will get
an error.

>From the point of view of someone *implementing* this function, the
Foo constraint *removes* some restriction: if there was no Foo
constraint you would not be able to do anything with any arguments of
type 'a'; given the Foo constraint you can do anything you could have
done without it, *plus* you can use any Foo methods.

-Brent



------------------------------

Message: 4
Date: Wed, 20 Jul 2011 23:58:16 +0200
From: Thomas <hask...@phirho.com>
Subject: [Haskell-beginners] Typeclasses vs. Data
To: beginners@haskell.org
Message-ID: <4e274f78.4020...@phirho.com>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed

Hello!

Trying to rewrite a program I ran into a type problem with typeclasses.

It's a mini-interpreter, the essential (extremely reduced) part is:

eval e k = case (car e) of
      (Id "begin") ->  eval_begin (cdr e) k
eval_begin e k = eval (car e) (if isNull (cdr e) then k else (BeginCont 
k (cdr e)))

Using "data" to define my data all is well:

data Continuation =
      BeginCont Continuation Expression
resume k e = case k of
        BeginCont k' es -> eval_begin es k'

Unfortunately when trying to extend the program by other types of 
"Continuation" I must add to the data definition and add a matching 
clause to "resume". That is I must modify the core module.
So I tried to decouple this using a typeclass like so:

class Continuation a where
    resume :: a -> Expression -> Expression

data BeginCont a = BeginCont a Expression deriving (Show)
instance (Continuation a) => Continuation (BeginCont a) where
   resume (BeginCont k es) v = eval_begin es k

This, however, results in an "infinite type" error.

Is there a way to make the typeclass version typecheck?
If not: How can one decouple this code in Haskell?

What also puzzles me are the differences in "infinite" types.
The above data declaration for "Continuation" is essentially infinite, 
too. But it works. And I thought I had understood this part...

Any hints greatly appreciated!
Thanks in advance,
Thomas


PS:
The minimal "program" to get it type check is:

data Expression = Null | Num Int | Id String | List [Expression]
      deriving (Eq, Show)

cdr :: Expression -> Expression
cdr (List []) = error "cdr Null !"
cdr (List (_:[])) = Null
cdr (List (l:ls)) = List ls

car :: Expression -> Expression
car (List l) = head l

isNull Null = True
isNull _ = False

eval e k = case (car e) of
      (Id "begin") ->  eval_begin (cdr e) k

eval_begin e k = eval (car e) (if isNull (cdr e) then k else (BeginCont 
k (cdr e)))

-- replace the following 5 lines...
data Continuation =
      BeginCont Continuation Expression

resume k e = case k of
        BeginCont k' es -> eval_begin es k'

{- ... with these to see the error
class Continuation a where
    resume :: a -> Expression -> Expression

data BeginCont a = BeginCont a Expression deriving (Show)
instance (Continuation a) => Continuation (BeginCont a) where
   resume (BeginCont k es) v = eval_begin es k
-]



------------------------------

Message: 5
Date: Wed, 20 Jul 2011 18:18:42 -0400
From: David Place <d...@vidplace.com>
Subject: Re: [Haskell-beginners] Typeclasses vs. Data
To: Thomas <hask...@phirho.com>
Cc: beginners@haskell.org
Message-ID: <79c7919a-4b97-4219-a2a4-09428a5d8...@vidplace.com>
Content-Type: text/plain; charset=us-ascii

On Jul 20, 2011, at 5:58 PM, Thomas wrote:

> class Continuation a where
>   resume :: a -> Expression -> Expression
> 
> data BeginCont a = BeginCont a Expression deriving (Show)
> instance (Continuation a) => Continuation (BeginCont a) where
>  resume (BeginCont k es) v = eval_begin es k

I think we need to know the definition of Expression.  if define it with a 
dummy type

eval_begin a b = a
type Expression = Int

this code fragment compiles.  Would you send a code fragment that will yield 
the error?
____________________
David Place   
Owner, Panpipes Ho! LLC
http://panpipesho.com
d...@vidplace.com






------------------------------

Message: 6
Date: Wed, 20 Jul 2011 18:23:49 -0400
From: David Place <d...@vidplace.com>
Subject: Re: [Haskell-beginners] Typeclasses vs. Data
To: Thomas <hask...@phirho.com>
Cc: beginners@haskell.org
Message-ID: <c55f6599-3b71-424f-b294-789f97cee...@vidplace.com>
Content-Type: text/plain; charset=us-ascii

Please disregard my previous message.  I didn't read your message carefully 
enough.
____________________
David Place   
Owner, Panpipes Ho! LLC
http://panpipesho.com
d...@vidplace.com



On Jul 20, 2011, at 5:58 PM, Thomas wrote:

> Hello!
> 
> Trying to rewrite a program I ran into a type problem with typeclasses.
> 
> It's a mini-interpreter, the essential (extremely reduced) part is:
> 
> eval e k = case (car e) of
>     (Id "begin") ->  eval_begin (cdr e) k
> eval_begin e k = eval (car e) (if isNull (cdr e) then k else (BeginCont k 
> (cdr e)))
> 
> Using "data" to define my data all is well:
> 
> data Continuation =
>     BeginCont Continuation Expression
> resume k e = case k of
>       BeginCont k' es -> eval_begin es k'
> 
> Unfortunately when trying to extend the program by other types of 
> "Continuation" I must add to the data definition and add a matching clause to 
> "resume". That is I must modify the core module.
> So I tried to decouple this using a typeclass like so:
> 
> class Continuation a where
>   resume :: a -> Expression -> Expression
> 
> data BeginCont a = BeginCont a Expression deriving (Show)
> instance (Continuation a) => Continuation (BeginCont a) where
>  resume (BeginCont k es) v = eval_begin es k
> 
> This, however, results in an "infinite type" error.
> 
> Is there a way to make the typeclass version typecheck?
> If not: How can one decouple this code in Haskell?
> 
> What also puzzles me are the differences in "infinite" types.
> The above data declaration for "Continuation" is essentially infinite, too. 
> But it works. And I thought I had understood this part...
> 
> Any hints greatly appreciated!
> Thanks in advance,
> Thomas
> 
> 
> PS:
> The minimal "program" to get it type check is:
> 
> data Expression = Null | Num Int | Id String | List [Expression]
>     deriving (Eq, Show)
> 
> cdr :: Expression -> Expression
> cdr (List []) = error "cdr Null !"
> cdr (List (_:[])) = Null
> cdr (List (l:ls)) = List ls
> 
> car :: Expression -> Expression
> car (List l) = head l
> 
> isNull Null = True
> isNull _ = False
> 
> eval e k = case (car e) of
>     (Id "begin") ->  eval_begin (cdr e) k
> 
> eval_begin e k = eval (car e) (if isNull (cdr e) then k else (BeginCont k 
> (cdr e)))
> 
> -- replace the following 5 lines...
> data Continuation =
>     BeginCont Continuation Expression
> 
> resume k e = case k of
>       BeginCont k' es -> eval_begin es k'
> 
> {- ... with these to see the error
> class Continuation a where
>   resume :: a -> Expression -> Expression
> 
> data BeginCont a = BeginCont a Expression deriving (Show)
> instance (Continuation a) => Continuation (BeginCont a) where
>  resume (BeginCont k es) v = eval_begin es k
> -]
> 
> _______________________________________________
> Beginners mailing list
> Beginners@haskell.org
> http://www.haskell.org/mailman/listinfo/beginners




------------------------------

Message: 7
Date: Thu, 21 Jul 2011 00:26:19 +0200
From: Thomas <hask...@phirho.com>
Subject: Re: [Haskell-beginners] Typeclasses vs. Data
To: David Place <d...@vidplace.com>
Cc: beginners@haskell.org
Message-ID: <4e27560b.1060...@phirho.com>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed

Hello David!

Thank you for taking the time.
Here is a complete fragment that shows the error:

data Expression = Null | Num Int | Id String | List [Expression]
      deriving (Eq, Show)

cdr :: Expression -> Expression
cdr (List []) = error "cdr Null !"
cdr (List (_:[])) = Null
cdr (List (l:ls)) = List ls

car :: Expression -> Expression
car (List l) = head l
car n = error (show n)

isNull Null = True
isNull _ = False

eval e k = case (car e) of
      (Id "begin") ->  eval_begin (cdr e) k

eval_begin e k = eval (car e) (if isNull (cdr e) then k else (BeginCont 
k (cdr e)))

class Continuation a where
    resume :: a -> Expression -> Expression

data BeginCont a = BeginCont a Expression deriving (Show)
instance (Continuation a) => Continuation (BeginCont a) where
   resume (BeginCont k es) v = eval_begin es k

Regards,
Thomas



On 21.07.2011 00:18, David Place wrote:
> On Jul 20, 2011, at 5:58 PM, Thomas wrote:
>
>> class Continuation a where
>>    resume :: a ->  Expression ->  Expression
>>
>> data BeginCont a = BeginCont a Expression deriving (Show)
>> instance (Continuation a) =>  Continuation (BeginCont a) where
>>   resume (BeginCont k es) v = eval_begin es k
>
> I think we need to know the definition of Expression.  if define it with a 
> dummy type
>
> eval_begin a b = a
> type Expression = Int
>
> this code fragment compiles.  Would you send a code fragment that will yield 
> the error?
> ____________________
> David Place
> Owner, Panpipes Ho! LLC
> http://panpipesho.com
> d...@vidplace.com
>
>




------------------------------

Message: 8
Date: Wed, 20 Jul 2011 18:40:45 -0400
From: David Place <d...@vidplace.com>
Subject: Re: [Haskell-beginners] Typeclasses vs. Data
To: Thomas <hask...@phirho.com>
Cc: beginners@haskell.org
Message-ID: <1cda3bbb-7172-4a15-9b64-daf7a1273...@vidplace.com>
Content-Type: text/plain; charset=iso-8859-1

On Jul 20, 2011, at 6:26 PM, Thomas wrote:

> Thank you for taking the time.
> Here is a complete fragment that shows the error:

Hi, Thomas.

I'm very sympathetic.  I hate it when I get an error like this.  I looked at 
your code and the solution didn't jump off the page, maybe it will for someone 
else.  In the meantime, I suggest this strategy.  Carefully give type 
signatures to all of your functions.  This way you can help the type checker 
give better error messages.  The type inference algorithm can go away into 
crazy land if you give it a nonsense definition.

___________________
David Place   
Owner, Panpipes Ho! LLC
http://panpipesho.com
d...@vidplace.com






------------------------------

_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://www.haskell.org/mailman/listinfo/beginners


End of Beginners Digest, Vol 37, Issue 40
*****************************************

Reply via email to