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. Re: Re: Classes in Polymorphic Constructors
(Brandon S Allbery KF8NH)
2. Re: Offside rule for function arguments? (Isaac Dupree)
3. Re: Offside rule for function arguments?
(Brandon S Allbery KF8NH)
4. Re: Re: Classes in Polymorphic Constructors (Isaac Dupree)
5. Re: Offside rule for function arguments? (Daniel Fischer)
6. Re: Classes in Polymorphic Constructors (John Smith)
7. Re: Offside rule for function arguments? (Isaac Dupree)
8. Re: Re: Classes in Polymorphic Constructors
(Brandon S Allbery KF8NH)
9. typeclass confusion (Greg)
----------------------------------------------------------------------
Message: 1
Date: Mon, 23 Aug 2010 13:28:01 -0400
From: Brandon S Allbery KF8NH <[email protected]>
Subject: Re: [Haskell-beginners] Re: Classes in Polymorphic
Constructors
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=UTF-8
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On 8/23/10 12:12 , John Smith wrote:
> On 23/08/2010 18:32, Ertugrul Soeylemez wrote:
>> John Smith<[email protected]> wrote:
>>
>>> Why can polymorphic data constructors not be instantiated as a class?
>>> (not sure if I used the right terminology there)
>>>
>>> For example,
>>>
>>> a = [1,True]::[Show]
>>> b = "foo":a
>>> c = map show b
>>>
>>> This would obviate the need for wrapper types
>>
>> Your type signature doesn't make sense. You are confusing type classes
>> with types. Show is a type class.
>
> My question was why doesn't the type system allow classes to be used in this
> way. It's the equivalent of a base class or interface in OO.
Typeclasses are not classes, and Haskell values are not objects. In OO
languages, objects carry around dictionaries with full details of what they
can do. Haskell values, on the other hand, don't actually carry around
anything; what they can do is specified by the type. If the type is (Show a
=> [a]), that means the *only* thing you can do with an (a) is to call
(show) on it.
(1) Since this is almost certainly not what you intend, Haskell insists you
acknowledge that by specifying the type as ([forall a. Show a => a]), making
it explicit that the scope of (a) is limited to inside the brackets ---
meaning that, since anything wanting to use it has to go through the
brackets, *all* it knows is that it can invoke (show) on it.
(2) Again, values are not objects --- there is no method dictionary hidden
inside of them. Typeclass dictionaries are carried *outside* of values, as
hidden arguments to functions that are declared with types that are
typeclass members. Which is why you can't say (a = [1,True] :: [forall a.
Show a => a]): there's nowhere to put the dictionary in the value
([1,True]). This is why a wrapper is required; the wrapper provides a place
for the hidden argument.
Summary: If you want an OO language, use an OO language. Haskell isn't one.
There are some outdated examples of OO extensions for Haskell that I don't
think are maintained any more, notably "OOHaskell". They're not maintained
due to lack of interest. If you want such a thing, you'll have to modernize
it yourself.
- --
brandon s. allbery [linux,solaris,freebsd,perl] [email protected]
system administrator [openafs,heimdal,too many hats] [email protected]
electrical and computer engineering, carnegie mellon university KF8NH
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.10 (Darwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iEYEARECAAYFAkxyr6EACgkQIn7hlCsL25XW/QCZAcpQFDxw/ukQlOpPn5zA18tE
vH0AoIh944GcFo1ASFoLxvIHldY9v5DR
=F+gL
-----END PGP SIGNATURE-----
------------------------------
Message: 2
Date: Mon, 23 Aug 2010 14:56:18 -0400
From: Isaac Dupree <[email protected]>
Subject: Re: [Haskell-beginners] Offside rule for function arguments?
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
On 08/23/10 02:33, John Smith wrote:
> Why doesn't Haskell allow something like this?
>
> fac 0 = 0
> 1 = 1
> x = x * fac (x-1)
>
> This would be clearer than repeating the function name each time, and
> follow the same pattern as guards and case.
Layout is detected and parsed when and only when it is preceded by
'where', 'let', 'do', or 'of'. So Haskell would have to have some such
keyword to indicate "let the layout begin!" -- which could make it a bit
uglier -- but no I don't know why. Sometimes where there are tons of
cases I define the function using 'case' instead -- I probably wouldn't
for your above example, but to show how it'd be written,
fac x = case x of
0 -> 0
1 -> 1
_ -> x * fac (x-1)
------------------------------
Message: 3
Date: Mon, 23 Aug 2010 15:02:50 -0400
From: Brandon S Allbery KF8NH <[email protected]>
Subject: Re: [Haskell-beginners] Offside rule for function arguments?
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=UTF-8
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On 8/23/10 14:56 , Isaac Dupree wrote:
> On 08/23/10 02:33, John Smith wrote:
>> Why doesn't Haskell allow something like this?
>>
>> fac 0 = 0
>> 1 = 1
>> x = x * fac (x-1)
>>
>> This would be clearer than repeating the function name each time, and
>> follow the same pattern as guards and case.
>
> Layout is detected and parsed when and only when it is preceded by 'where',
> 'let', 'do', or 'of'. So Haskell would have to have some such keyword to
I think the next question is "so how do guards work?"
- --
brandon s. allbery [linux,solaris,freebsd,perl] [email protected]
system administrator [openafs,heimdal,too many hats] [email protected]
electrical and computer engineering, carnegie mellon university KF8NH
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.10 (Darwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iEYEARECAAYFAkxyxdoACgkQIn7hlCsL25VVqgCg0tLmPDFClCTgr1ExoSFZOMMT
ri4AoM2MX9vRXMo0YHuiX4PIgPiGi/GV
=l0lN
-----END PGP SIGNATURE-----
------------------------------
Message: 4
Date: Mon, 23 Aug 2010 15:12:15 -0400
From: Isaac Dupree <[email protected]>
Subject: Re: [Haskell-beginners] Re: Classes in Polymorphic
Constructors
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=UTF-8; format=flowed
On 08/23/10 13:28, Brandon S Allbery KF8NH wrote:
> Summary: If you want an OO language, use an OO language. Haskell isn't one.
>
> There are some outdated examples of OO extensions for Haskell that I don't
> think are maintained any more, notably "OOHaskell". They're not maintained
> due to lack of interest. If you want such a thing, you'll have to modernize
> it yourself.
I wouldn't take that advice too literally-- When I was first learning
Haskell I was interested in O'Haskell (or whatever it was called), but
now that I've used Haskell for longer, I get along quite happily with
its type-system and way of thinking about things, and rarely want OO.
-Isaac
------------------------------
Message: 5
Date: Mon, 23 Aug 2010 21:14:43 +0200
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] Offside rule for function arguments?
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset="utf-8"
On Monday 23 August 2010 21:02:50, Brandon S Allbery KF8NH wrote:
> On 8/23/10 14:56 , Isaac Dupree wrote:
> > On 08/23/10 02:33, John Smith wrote:
> >> Why doesn't Haskell allow something like this?
> >>
> >> fac 0 = 0
> >> 1 = 1
> >> x = x * fac (x-1)
> >>
> >> This would be clearer than repeating the function name each time, and
> >> follow the same pattern as guards and case.
> >
> > Layout is detected and parsed when and only when it is preceded by
> > 'where', 'let', 'do', or 'of'. So Haskell would have to have some
> > such keyword to
>
> I think the next question is "so how do guards work?"
Not by layout:
function :: Int -> Int -> Int -> Bool
function x y z | even x = y > z | odd y = even (z-x) | otherwise = even z
parses fine.
Guards are introduced by the token `|', they need not be aligned, you can
have multiple on the same line.
------------------------------
Message: 6
Date: Mon, 23 Aug 2010 22:17:18 +0300
From: John Smith <[email protected]>
Subject: [Haskell-beginners] Re: Classes in Polymorphic Constructors
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=UTF-8; format=flowed
On 23/08/2010 20:28, Brandon S Allbery KF8NH wrote:
> On 8/23/10 12:12 , John Smith wrote:
>> On 23/08/2010 18:32, Ertugrul Soeylemez wrote:
>>> John Smith<[email protected]> wrote:
>>>
>>>> Why can polymorphic data constructors not be instantiated as a class?
>>>> (not sure if I used the right terminology there)
>>>>
>>>> For example,
>>>>
>>>> a = [1,True]::[Show]
>>>> b = "foo":a
>>>> c = map show b
>>>>
>>>> This would obviate the need for wrapper types
>>>
>>> Your type signature doesn't make sense. You are confusing type classes
>>> with types. Show is a type class.
>>
>> My question was why doesn't the type system allow classes to be used in this
>> way. It's the equivalent of a base class or interface in OO.
>
> Typeclasses are not classes, and Haskell values are not objects. In OO
> languages, objects carry around dictionaries with full details of what they
> can do. Haskell values, on the other hand, don't actually carry around
> anything; what they can do is specified by the type. If the type is (Show a
> => [a]), that means the *only* thing you can do with an (a) is to call
> (show) on it.
>
> (1) Since this is almost certainly not what you intend,
Wouldn't this be a useful feature? For example, [Show] could contain a list of
values for serialising to strings, and
ditto for any other typeclass. When you say "Since this is almost certainly not
what you intend", is there something
else which could be intended by such code?
> Haskell insists you
> acknowledge that by specifying the type as ([forall a. Show a => a]), making
> it explicit that the scope of (a) is limited to inside the brackets ---
> meaning that, since anything wanting to use it has to go through the
> brackets, *all* it knows is that it can invoke (show) on it.
>
> (2) Again, values are not objects --- there is no method dictionary hidden
> inside of them. Typeclass dictionaries are carried *outside* of values, as
> hidden arguments to functions that are declared with types that are
> typeclass members. Which is why you can't say (a = [1,True] :: [forall a.
> Show a => a]): there's nowhere to put the dictionary in the value
> ([1,True]). This is why a wrapper is required; the wrapper provides a place
> for the hidden argument.
>
> Summary: If you want an OO language, use an OO language. Haskell isn't one.
>
> There are some outdated examples of OO extensions for Haskell that I don't
> think are maintained any more, notably "OOHaskell". They're not maintained
> due to lack of interest. If you want such a thing, you'll have to modernize
> it yourself.
I don't want OO, just for typeclasses to be usable as types in polymorphism,
seeing as both are equally relevant as a
definition of constraints. (There's probably a better way to word that.)
------------------------------
Message: 7
Date: Mon, 23 Aug 2010 15:17:47 -0400
From: Isaac Dupree <[email protected]>
Subject: Re: [Haskell-beginners] Offside rule for function arguments?
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=UTF-8; format=flowed
On 08/23/10 15:02, Brandon S Allbery KF8NH wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> On 8/23/10 14:56 , Isaac Dupree wrote:
>> On 08/23/10 02:33, John Smith wrote:
>>> Why doesn't Haskell allow something like this?
>>>
>>> fac 0 = 0
>>> 1 = 1
>>> x = x * fac (x-1)
>>>
>>> This would be clearer than repeating the function name each time, and
>>> follow the same pattern as guards and case.
>>
>> Layout is detected and parsed when and only when it is preceded by 'where',
>> 'let', 'do', or 'of'. So Haskell would have to have some such keyword to
>
> I think the next question is "so how do guards work?"
Weirdly! It's a bit like "|" is a prefix operator, at least when found
in this relevant parsing-context (and not e.g. in a list comprehension).
The guards don't need to line up either. I admit that I wasn't too
happy when I found out how guards parse. "|" looks way too symmetric of
a character for it to do that... Linebreaks are not required! :
fac x | x==0 = 0 | x==1 = 1 | otherwise = x * fac (x-1)
------------------------------
Message: 8
Date: Mon, 23 Aug 2010 15:34:30 -0400
From: Brandon S Allbery KF8NH <[email protected]>
Subject: Re: [Haskell-beginners] Re: Classes in Polymorphic
Constructors
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=UTF-8
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On 8/23/10 15:17 , John Smith wrote:
> On 23/08/2010 20:28, Brandon S Allbery KF8NH wrote:
>> Typeclasses are not classes, and Haskell values are not objects. In OO
>> languages, objects carry around dictionaries with full details of what they
>> can do. Haskell values, on the other hand, don't actually carry around
>> anything; what they can do is specified by the type. If the type is (Show a
>> => [a]), that means the *only* thing you can do with an (a) is to call
>> (show) on it.
>>
>> (1) Since this is almost certainly not what you intend,
>
> Wouldn't this be a useful feature? For example, [Show] could contain a list
It can be useful at times, which is why you can write it out the long way.
But consider something like ([forall n. Num n => n]); the dictionary
contains the basic math operations (see the definition of Num; you also get
Eq and Show, but nothing else. Not even Ord, since complex numbers don't
have a well defined ordering) and they are specialized for the exact type of
the object, but you don't know what that type is so you can't really apply
it to anything else. (Not even to another member of the list, since it
doesn't have the type of that object, it has the type (forall n. Num n => n).)
On the other hand, carrying around type and/or method information for every
value is fairly expensive, and lazy languages are already slow because of
the extra work (basically, "lazy" means every expression is actually a
closure which produces the value of that expression when invoked). This is
what "unboxing" is about, which you'll see mentioned in almost every
discussion of optimization or performance in Haskell). Including a method
dictionary means *another* level of indirection for every expression and
every evaluation step, and then if you make the dictionary lazy as well then
it's still another level of indirection per evaluation.
> of values for serialising to strings, and ditto for any other typeclass.
> When you say "Since this is almost certainly not what you intend", is there
> something else which could be intended by such code?
Most people, on seeing that, would expect it to mean "I get to use all the
operations legal on the type of the value I gave it, as long as that type is
a member of Show". But it actually means "I can only use operations legal
on values whose type is a member of Show".
> I don't want OO, just for typeclasses to be usable as types in polymorphism,
> seeing as both are equally relevant as a definition of constraints. (There's
> probably a better way to word that.)
You may have phrased that wrongly indeed; I would recognize that as
subtyping, which is a form of dependent types. Which is a rather more
complex ball of type spaghetti.
- --
brandon s. allbery [linux,solaris,freebsd,perl] [email protected]
system administrator [openafs,heimdal,too many hats] [email protected]
electrical and computer engineering, carnegie mellon university KF8NH
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.10 (Darwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iEYEARECAAYFAkxyzUYACgkQIn7hlCsL25VZVACgvX0aLQwioqkOSByVdfA9jAo5
MPIAoLR55POz5SjHki7Pcui7nmn1fS2u
=8aCZ
-----END PGP SIGNATURE-----
------------------------------
Message: 9
Date: Mon, 23 Aug 2010 19:33:21 -0700 (PDT)
From: Greg <[email protected]>
Subject: [Haskell-beginners] typeclass confusion
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset="iso-8859-1"
Hi--
I'm back to trying to teach myself Haskell, and I've already got myself into a
muddle again. I've begun playing a bit with the type system, and typeclasses
and figured I'd build a type to hold angular values since it would be nice to
force the type system to check whether I'm using degrees or radians:
data Angle a = Radians a
| Degrees a
deriving (Eq, Show)
Then I decided I wanted to create a (gratuitous) type class to abstract out the
radian/degree conversions:
class Angular a where
rad :: a -> a
rad x = pi * (deg x) / 180
deg :: a -> a
deg x = 180 * (rad x) / pi
Then tried to make Angle an instance of Angular (such as Float in an instance
of Floating):
instance Angular (Angle a) where
rad (Radians x) = x
deg (Degrees x) = x
I've removed all the context clauses, rather than pick one of many equally
broken implementations to share, because that seems to be a large part of where
my problems are.
Is this just an issue of syntax, or am I doing something fundamentally wrong?
Thanks--
Greg
-------------- next part --------------
Skipped content of type multipart/related
------------------------------
_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners
End of Beginners Digest, Vol 26, Issue 46
*****************************************