Idiomatic way to avoid type class instance definitions for Int and Integer separately

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

Untested, but you might try:
instance (Num t) => YesNo t where ....
-deech
On Tue, Mar 15, 2011 at 2:21 PM, Amitava Shee
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 Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

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
Untested, but you might try:
instance (Num t) => YesNo t where ....
-deech
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
On Tue, Mar 15, 2011 at 2:21 PM, Amitava Shee
wrote: the idiomatic way?
Thanks & Regards, Amitava Shee
_______________________________________________ Beginners mailing list Beginners@haskell.org 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

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

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).

I've had this problem for a while now, and it's about time I recognize I need help :P I've written a few programs in Haskell that excel at numeric and/or complex computations; I love the efficiency of the language. I do not love, however, writing GUIs for this pieces of software. Perhaps it's the echoes of bad times past when trying to install gtk2hs, or that I know I can crank up some decent UIs in other languages faster. Whatever the reason, I've been thinking of writing the GUI for my programs as an extension of the program itself, possibly in another language. Assuming the GUI is written in, say, Python, and want to pass data to the underlying Haskell program, how to send it? I'd like to avoid touching the disk, but I don't have enough experience to answer my own questions: - command line arguments? what if data is large? - client GUI, server Haskell program, and unix sockets? is there a simpler way? Any insights, comments, or experience shared will be greatly appreciated. Thanks.

On Tue, 12 Apr 2011 00:45:57 -0300
MAN
I've had this problem for a while now, and it's about time I recognize I need help :P I've written a few programs in Haskell that excel at numeric and/or complex computations; I love the efficiency of the language. I do not love, however, writing GUIs for this pieces of software. Perhaps it's the echoes of bad times past when trying to install gtk2hs, or that I know I can crank up some decent UIs in other languages faster. Whatever the reason, I've been thinking of writing the GUI for my programs as an extension of the program itself, possibly in another language. Assuming the GUI is written in, say, Python, and want to pass data to the underlying Haskell program, how to send it? I'd like to avoid touching the disk, but I don't have enough experience to answer my own questions: - command line arguments? what if data is large?
Pipes? At least on Unix. One of the two halves of the program starts the other, with standard input & output for the child going to/from the parent.
- client GUI, server Haskell program, and unix sockets? is there a simpler way?
These days, pipes seem to be built on top of/using the same
architecture as sockets, so the difference between this and my pipes
suggestion is that the pipes doesn't have to deal with rendezvous
issues.
Come to think of it, Joel Bartlett at DECWRL had a system called ezd
that looked a lot like this, except he did it the other way around:
his server (written in Scheme) provided high-level (for the time)
graphics primitives whose interface was a pair of pipes. I played with
it some back in the day, and I recall it as pretty spiffy (especially
using Bartlett's Scheme compiler for the front end).
And the internet hasn't forgotten it! I found a copy of his WRL Tech
Report on it:
http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-91-6.html

Come to think of it, Joel Bartlett at DECWRL had a system called ezd that looked a lot like this, except he did it the other way around: his server (written in Scheme) provided high-level (for the time) graphics primitives whose interface was a pair of pipes. I played with it some back in the day, and I recall it as pretty spiffy (especially using Bartlett's Scheme compiler for the front end).
And the internet hasn't forgotten it! I found a copy of his WRL Tech Report on it: http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-91-6.html
Thanks for the link Mike - I get a feeling that my attempt at https://github.com/ckkashyap/Chitra is similar in spirit :) I'll be getting back to it soon.

Pipes seem a bit better than sockets. I'm investigating the possibility right now. As I read about sockets I remembered there's Haskell bindings to DBus... has anybody used it? ever? (last update was over 4 years ago). El mar, 12-04-2011 a las 00:45 -0400, Mike Meyer escribió:
On Tue, 12 Apr 2011 00:45:57 -0300 MAN
wrote: I've had this problem for a while now, and it's about time I recognize I need help :P I've written a few programs in Haskell that excel at numeric and/or complex computations; I love the efficiency of the language. I do not love, however, writing GUIs for this pieces of software. Perhaps it's the echoes of bad times past when trying to install gtk2hs, or that I know I can crank up some decent UIs in other languages faster. Whatever the reason, I've been thinking of writing the GUI for my programs as an extension of the program itself, possibly in another language. Assuming the GUI is written in, say, Python, and want to pass data to the underlying Haskell program, how to send it? I'd like to avoid touching the disk, but I don't have enough experience to answer my own questions: - command line arguments? what if data is large?
Pipes? At least on Unix. One of the two halves of the program starts the other, with standard input & output for the child going to/from the parent.
- client GUI, server Haskell program, and unix sockets? is there a simpler way?
These days, pipes seem to be built on top of/using the same architecture as sockets, so the difference between this and my pipes suggestion is that the pipes doesn't have to deal with rendezvous issues.
Come to think of it, Joel Bartlett at DECWRL had a system called ezd that looked a lot like this, except he did it the other way around: his server (written in Scheme) provided high-level (for the time) graphics primitives whose interface was a pair of pipes. I played with it some back in the day, and I recall it as pretty spiffy (especially using Bartlett's Scheme compiler for the front end).
And the internet hasn't forgotten it! I found a copy of his WRL Tech Report on it: http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-91-6.html

Hi,
Sometimes what I like to do is just make my backend program read
commands from stdin and answer back on stdout.
That keeps it simple, plus it's easy to test the backend.
Then from the frontend you can start the backend using pipes as
described by Mike earlier. From Perl I would probably use something
like http://search.cpan.org/~rjbs/perl-5.12.3/ext/IPC-Open2/lib/IPC/Open2.pm,
there probably is something similar for Python.
Patrick
On Tue, Apr 12, 2011 at 11:35 AM, MAN
Pipes seem a bit better than sockets. I'm investigating the possibility right now. As I read about sockets I remembered there's Haskell bindings to DBus... has anybody used it? ever? (last update was over 4 years ago).
El mar, 12-04-2011 a las 00:45 -0400, Mike Meyer escribió:
On Tue, 12 Apr 2011 00:45:57 -0300 MAN
wrote: I've had this problem for a while now, and it's about time I recognize I need help :P I've written a few programs in Haskell that excel at numeric and/or complex computations; I love the efficiency of the language. I do not love, however, writing GUIs for this pieces of software. Perhaps it's the echoes of bad times past when trying to install gtk2hs, or that I know I can crank up some decent UIs in other languages faster. Whatever the reason, I've been thinking of writing the GUI for my programs as an extension of the program itself, possibly in another language. Assuming the GUI is written in, say, Python, and want to pass data to the underlying Haskell program, how to send it? I'd like to avoid touching the disk, but I don't have enough experience to answer my own questions: - command line arguments? what if data is large?
Pipes? At least on Unix. One of the two halves of the program starts the other, with standard input & output for the child going to/from the parent.
- client GUI, server Haskell program, and unix sockets? is there a simpler way?
These days, pipes seem to be built on top of/using the same architecture as sockets, so the difference between this and my pipes suggestion is that the pipes doesn't have to deal with rendezvous issues.
Come to think of it, Joel Bartlett at DECWRL had a system called ezd that looked a lot like this, except he did it the other way around: his server (written in Scheme) provided high-level (for the time) graphics primitives whose interface was a pair of pipes. I played with it some back in the day, and I recall it as pretty spiffy (especially using Bartlett's Scheme compiler for the front end).
And the internet hasn't forgotten it! I found a copy of his WRL Tech Report on it: http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-91-6.html
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
-- ===================== Patrick LeBoutillier Rosemère, Québec, Canada

I thinks you're all right. DBus is not the tool for this job (it does more, and is slower). Alas, pipes it is. Thanks, everyone! El mar, 12-04-2011 a las 21:13 -0400, Patrick LeBoutillier escribió:
Hi,
Sometimes what I like to do is just make my backend program read commands from stdin and answer back on stdout.
That keeps it simple, plus it's easy to test the backend.
Then from the frontend you can start the backend using pipes as described by Mike earlier. From Perl I would probably use something like http://search.cpan.org/~rjbs/perl-5.12.3/ext/IPC-Open2/lib/IPC/Open2.pm, there probably is something similar for Python.
Patrick
On Tue, Apr 12, 2011 at 11:35 AM, MAN
wrote: Pipes seem a bit better than sockets. I'm investigating the possibility right now. As I read about sockets I remembered there's Haskell bindings to DBus... has anybody used it? ever? (last update was over 4 years ago).
El mar, 12-04-2011 a las 00:45 -0400, Mike Meyer escribió:
On Tue, 12 Apr 2011 00:45:57 -0300 MAN
wrote: I've had this problem for a while now, and it's about time I recognize I need help :P I've written a few programs in Haskell that excel at numeric and/or complex computations; I love the efficiency of the language. I do not love, however, writing GUIs for this pieces of software. Perhaps it's the echoes of bad times past when trying to install gtk2hs, or that I know I can crank up some decent UIs in other languages faster. Whatever the reason, I've been thinking of writing the GUI for my programs as an extension of the program itself, possibly in another language. Assuming the GUI is written in, say, Python, and want to pass data to the underlying Haskell program, how to send it? I'd like to avoid touching the disk, but I don't have enough experience to answer my own questions: - command line arguments? what if data is large?
Pipes? At least on Unix. One of the two halves of the program starts the other, with standard input & output for the child going to/from the parent.
- client GUI, server Haskell program, and unix sockets? is there a simpler way?
These days, pipes seem to be built on top of/using the same architecture as sockets, so the difference between this and my pipes suggestion is that the pipes doesn't have to deal with rendezvous issues.
Come to think of it, Joel Bartlett at DECWRL had a system called ezd that looked a lot like this, except he did it the other way around: his server (written in Scheme) provided high-level (for the time) graphics primitives whose interface was a pair of pipes. I played with it some back in the day, and I recall it as pretty spiffy (especially using Bartlett's Scheme compiler for the front end).
And the internet hasn't forgotten it! I found a copy of his WRL Tech Report on it: http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-91-6.html
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

On 15 March 2011 19:21, Amitava Shee
*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-evaluatio... Hope this helps, -- Ozgur Akgun
participants (8)
-
aditya siram
-
Amitava Shee
-
C K Kashyap
-
Daniel Fischer
-
MAN
-
Mike Meyer
-
Ozgur Akgun
-
Patrick LeBoutillier