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. Idiomatic way to avoid type class instance definitions for
Int and Integer separately (Amitava Shee)
2. Re: Idiomatic way to avoid type class instance definitions
for Int and Integer separately (aditya siram)
3. Re: Idiomatic way to avoid type class instance definitions
for Int and Integer separately (Ozgur Akgun)
4. Re: Idiomatic way to avoid type class instance definitions
for Int and Integer separately (Amitava Shee)
5. Re: Idiomatic way to avoid type class instance definitions
for Int and Integer separately (Daniel Fischer)
6. Re: Idiomatic way to avoid type class instance definitions
for Int and Integer separately (Daniel Fischer)
----------------------------------------------------------------------
Message: 1
Date: Tue, 15 Mar 2011 15:21:40 -0400
From: Amitava Shee <[email protected]>
Subject: [Haskell-beginners] Idiomatic way to avoid type class
instance definitions for Int and Integer separately
To: [email protected]
Message-ID:
<[email protected]>
Content-Type: text/plain; charset="iso-8859-1"
While reading "Learn You a Haskell for Great Good!" I came across the YesNo
type class
I tried a minimal version as below
module Kind where
class Yesno a where
yesno :: a -> Bool
instance Yesno Int where
yesno 0 = False
yesno _ = True
I was surprised to get an error
*Kind> :load kind.hs
[1 of 1] Compiling Kind ( kind.hs, interpreted )
Ok, modules loaded: Kind.
*Kind> yesno 10
<interactive>:1:6:
Ambiguous type variable `t' in the constraints:
`Num t' arising from the literal `10' at <interactive>:1:6-7
`Yesno t' arising from a use of `yesno' at <interactive>:1:0-7
Probable fix: add a type signature that fixes these type variable(s)
Turns out 10 in this instance is an Integer and I have not defined Yesno
over Integer
Easy fix - just define an instance over Integer
instance Yesno Integer where
yesno 0 = False
yesno _ = True
My question - Is there a way to avoid this kind of boilerplate? What is the
idiomatic way?
Thanks & Regards,
Amitava Shee
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://www.haskell.org/pipermail/beginners/attachments/20110315/bbfce7f9/attachment-0001.htm>
------------------------------
Message: 2
Date: Tue, 15 Mar 2011 14:28:38 -0500
From: aditya siram <[email protected]>
Subject: Re: [Haskell-beginners] Idiomatic way to avoid type class
instance definitions for Int and Integer separately
To: Amitava Shee <[email protected]>
Cc: [email protected]
Message-ID:
<[email protected]>
Content-Type: text/plain; charset=ISO-8859-1
Untested, but you might try:
instance (Num t) => YesNo t where ....
-deech
On Tue, Mar 15, 2011 at 2:21 PM, Amitava Shee <[email protected]> wrote:
> While reading "Learn You a Haskell for Great Good!" I came across the YesNo
> type class
>
> I tried a minimal version as below
>
> module Kind where
>
> class Yesno a where
> ??? yesno :: a -> Bool
>
> instance Yesno Int where
> ??? yesno 0 = False
> ??? yesno _ = True
>
>
> I was surprised to get an error
>
> *Kind> :load kind.hs
> [1 of 1] Compiling Kind???????????? ( kind.hs, interpreted )
> Ok, modules loaded: Kind.
> *Kind> yesno 10
>
> <interactive>:1:6:
> ??? Ambiguous type variable `t' in the constraints:
> ????? `Num t' arising from the literal `10' at <interactive>:1:6-7
> ????? `Yesno t' arising from a use of `yesno' at <interactive>:1:0-7
> ??? Probable fix: add a type signature that fixes these type variable(s)
>
> Turns out 10 in this instance is an Integer and I have not defined Yesno
> over Integer
>
> Easy fix - just define an instance over Integer
>
> instance Yesno Integer where
> ??? yesno 0 = False
> ??? yesno _ = True
>
> My question - Is there a way to avoid this kind of boilerplate? What is the
> idiomatic way?
>
> Thanks & Regards,
> Amitava Shee
>
>
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://www.haskell.org/mailman/listinfo/beginners
>
>
------------------------------
Message: 3
Date: Tue, 15 Mar 2011 19:40:40 +0000
From: Ozgur Akgun <[email protected]>
Subject: Re: [Haskell-beginners] Idiomatic way to avoid type class
instance definitions for Int and Integer separately
To: Amitava Shee <[email protected]>
Cc: [email protected]
Message-ID:
<[email protected]>
Content-Type: text/plain; charset="utf-8"
On 15 March 2011 19:21, Amitava Shee <[email protected]> wrote:
> *Kind> yesno 10
>
> <interactive>:1:6:
> Ambiguous type variable `t' in the constraints:
> `Num t' arising from the literal `10' at <interactive>:1:6-7
> `Yesno t' arising from a use of `yesno' at <interactive>:1:0-7
> Probable fix: add a type signature that fixes these type variable(s)
>
The literal 10 has type (Num n => n), however, due to ghci's defaulting
rules, it defaults to Integer, hence the error you've experienced.
Try yesno (10 :: Int), and check section 2.4.5 of [1].
[1]
http://www.haskell.org/ghc/docs/7.0.2/html/users_guide/interactive-evaluation.html
Hope this helps,
--
Ozgur Akgun
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://www.haskell.org/pipermail/beginners/attachments/20110315/8e501d1b/attachment-0001.htm>
------------------------------
Message: 4
Date: Tue, 15 Mar 2011 15:43:59 -0400
From: Amitava Shee <[email protected]>
Subject: Re: [Haskell-beginners] Idiomatic way to avoid type class
instance definitions for Int and Integer separately
To: [email protected]
Message-ID:
<[email protected]>
Content-Type: text/plain; charset="iso-8859-1"
kind.hs:7:0:
Illegal instance declaration for `Yesno t'
(All instance types must be of the form (T a1 ... an)
where a1 ... an are type *variables*,
and each type variable appears at most once in the instance head.
Use -XFlexibleInstances if you want to disable this.)
In the instance declaration for `Yesno t'
Failed, modules loaded: none.
So, I added the suggested Pragma
{-# LANGUAGE FlexibleInstances #-}
module Kind where
....
Prelude> :l kind.hs
[1 of 1] Compiling Kind ( kind.hs, interpreted )
kind.hs:7:0:
Constraint is no smaller than the instance head
in the constraint: Num t
(Use -XUndecidableInstances to permit this)
In the instance declaration for `Yesno t'
Failed, modules loaded: none.
Adjusted pragma to
{-# LANGUAGE FlexibleInstances,
UndecidableInstances #-}
Prelude> :l kind.hs
[1 of 1] Compiling Kind ( kind.hs, interpreted )
Ok, modules loaded: Kind.
*Kind> yesno 10
True
*Kind> yesno 0
False
I am not sure if I understand the implications here. Did I introduce a bug?
-Amitava
On Tue, Mar 15, 2011 at 3:28 PM, aditya siram <[email protected]>wrote:
> Untested, but you might try:
>
> instance (Num t) => YesNo t where ....
>
> -deech
>
> On Tue, Mar 15, 2011 at 2:21 PM, Amitava Shee <[email protected]>
> wrote:
> > While reading "Learn You a Haskell for Great Good!" I came across the
> YesNo
> > type class
> >
> > I tried a minimal version as below
> >
> > module Kind where
> >
> > class Yesno a where
> > yesno :: a -> Bool
> >
> > instance Yesno Int where
> > yesno 0 = False
> > yesno _ = True
> >
> >
> > I was surprised to get an error
> >
> > *Kind> :load kind.hs
> > [1 of 1] Compiling Kind ( kind.hs, interpreted )
> > Ok, modules loaded: Kind.
> > *Kind> yesno 10
> >
> > <interactive>:1:6:
> > Ambiguous type variable `t' in the constraints:
> > `Num t' arising from the literal `10' at <interactive>:1:6-7
> > `Yesno t' arising from a use of `yesno' at <interactive>:1:0-7
> > Probable fix: add a type signature that fixes these type variable(s)
> >
> > Turns out 10 in this instance is an Integer and I have not defined Yesno
> > over Integer
> >
> > Easy fix - just define an instance over Integer
> >
> > instance Yesno Integer where
> > yesno 0 = False
> > yesno _ = True
> >
> > My question - Is there a way to avoid this kind of boilerplate? What is
> the
> > idiomatic way?
> >
> > Thanks & Regards,
> > Amitava Shee
> >
> >
> > _______________________________________________
> > Beginners mailing list
> > [email protected]
> > http://www.haskell.org/mailman/listinfo/beginners
> >
> >
>
--
Amitava Shee
Software Architect
There are two ways of constructing a software design. One is to make it so
simple that there are obviously no deficiencies; the other is to make it so
complicated that there are no obvious deficiencies. The first method is far
more difficult.
-- C. A. R. Hoare The Emperor's Old Clothes, CACM February 1981
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://www.haskell.org/pipermail/beginners/attachments/20110315/b55a66bb/attachment-0001.htm>
------------------------------
Message: 5
Date: Tue, 15 Mar 2011 20:58:03 +0100
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] Idiomatic way to avoid type class
instance definitions for Int and Integer separately
To: [email protected]
Cc: Amitava Shee <[email protected]>
Message-ID: <[email protected]>
Content-Type: Text/Plain; charset="iso-8859-1"
On Tuesday 15 March 2011 20:28:38, aditya siram wrote:
> Untested, but you might try:
>
> instance (Num t) => YesNo t where ....
Careful with that. That doesn't work as one expects at first, if you have
that and try to also have an
instance YesNo Bool where
yesno = id
you'll get a compiler error.
For instance selection, only the part after the "=>" in
instance (Num t) => YesNo t where ...
is taken into account, so that basically says
"every type [because every type is unifiable with 't'] is an instance of
YesNo - but if you try to use yesno on a type which is not an instance of
Num, you'll get a compile error".
You can allow both instance declarations by turning on
OverlappingInstances, but that's not something to do light-heartedly
because that opens the way for a number of other problems.
Regarding the original question, that sort of boilerplate is often
unnecessary because in real programmes, the type of yesno's argument can
usually be determined from the context, which isn't available at the ghci
prompt. At the prompt, you could specify the type of the argument directly,
ghci> yesno (10 :: Int)
True
which may be less inconvenient than adding instances to satisfy ghci's
defaulting algorithm.
Otherwise,
- if you know you don't need any other instances, deech's suggestion is
great
- if you know that using OverlappingInstances is safe, deech's suggestion
is great
- if you need other instances and can't/don't want to use
OverlappingInstances, you can reduce the burden of the boilerplate by using
preprocessor macros or Template Haskell (the latter is GHC only, so if you
want portability, it's macros or code generation).
------------------------------
Message: 6
Date: Tue, 15 Mar 2011 21:11:06 +0100
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] Idiomatic way to avoid type class
instance definitions for Int and Integer separately
To: [email protected]
Cc: Amitava Shee <[email protected]>
Message-ID: <[email protected]>
Content-Type: Text/Plain; charset="utf-8"
On Tuesday 15 March 2011 20:43:59, Amitava Shee wrote:
> kind.hs:7:0:
> Illegal instance declaration for `Yesno t'
> (All instance types must be of the form (T a1 ... an)
> where a1 ... an are type *variables*,
> and each type variable appears at most once in the instance
> head. Use -XFlexibleInstances if you want to disable this.)
> In the instance declaration for `Yesno t'
> Failed, modules loaded: none.
Yes, the language report specifies a fairly restricted form of legal
instance declarations, so to have an
instance Foo a where ...
or an
instance Bar (Either Int a) where ...
you need to turn on FlexibleInstances
>
> So, I added the suggested Pragma
> {-# LANGUAGE FlexibleInstances #-}
> module Kind where
> ....
>
> Prelude> :l kind.hs
> [1 of 1] Compiling Kind ( kind.hs, interpreted )
>
> kind.hs:7:0:
> Constraint is no smaller than the instance head
> in the constraint: Num t
> (Use -XUndecidableInstances to permit this)
> In the instance declaration for `Yesno t'
> Failed, modules loaded: none.
>
Yes, if the constraint is not smaller than the instance head, the compiler
doesn't know a priori that instance checking will terminate, so it asks you
to tell it to go ahead by enabling UndecidableInstances (which is perhaps a
too scary name). Despite its scary name, that is a relatively harmless
extension, it just allows the compiler to try and check instances where it
doesn't know in advance that checking will terminate. Even if the checking
doesn't terminate, it won't send the compiler into an infinite loop because
it has a context stack and doesn't try to use more steps than that allows
(you can set the size of the stack if the default size is too small for
your use-case). If checking terminates, it's fine.
> Adjusted pragma to
> {-# LANGUAGE FlexibleInstances,
> UndecidableInstances #-}
>
> Prelude> :l kind.hs
> [1 of 1] Compiling Kind ( kind.hs, interpreted )
> Ok, modules loaded: Kind.
>
> *Kind> yesno 10
> True
> *Kind> yesno 0
> False
>
> I am not sure if I understand the implications here.
All harmless. You just allowed more general forms of instance declarations
than specified in the report (see above) and told the compiler to try even
though it doesn't have an a priori guarantee that it will finish.
> Did I introduce a bug?
No. Unless possibly if you want further instances, see my previous mail.
>
> -Amitava
------------------------------
_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners
End of Beginners Digest, Vol 33, Issue 16
*****************************************