Re: [Haskell-cafe] Inheritance and Wrappers

2011-02-03 Thread Ozgur Akgun
On 3 February 2011 02:35, Brandon Moore brandon_m_mo...@yahoo.com wrote:

 Here's one thing to consider:

 Can you write a function

 f :: (Data a) = a - String
 f x = termTag x

 It would seem the Data a = Term a instance justifies
 this function, and it will always use the default instance.

 Now, what happens if f is applied to a value of some type
 T which is an instance of Data, but has a custom Term instance?


Great point, thanks!

I guess somehow you shouldn't be allowed to write that function f. I need
to think about this one.

-- 
Ozgur
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Inheritance and Wrappers

2011-02-02 Thread Brandon Moore

OK, what about this as a use case then. I want to create a type class 'Term' 
with only one function in it. The function returns a 'termTag' which labels 
the 

kind of a value in a DSL.  

class Term a where
   termTag :: a - String


A user of this type-class can happily provide an instance without any other 
type 

class requirement. However, I want those types which are instances of Data to 
be 

an instance of Term automatically. On top of that, I don't want to stop the 
user 

from creating a special instance for their data type.

I want to be able to write the following instance to accomplish that:

instance Data t = Term t where
termTag = show . toConstr


A much more predictable option is to provide this default implementation
as a function

termTagData :: (Data t) = (t - String)

and let the library clients use it in their instances if the behavior is fine:

instance Term MyT where
  termTag = termTagData

And if the user wants to write a more specific instance, they should be 
welcome 

to do so:

instance Term UserDT where
termTag (...) = ...

I am not very much interested in the technical details about how things 
currently are, I am more interested in a discussion about why (if?) this would 
be considered a design flaw?


Here's one thing to consider:

Can you write a function

f :: (Data a) = a - String
f x = termTag x

It would seem the Data a = Term a instance justifies
this function, and it will always use the default instance.

Now, what happens if f is applied to a value of some type
T which is an instance of Data, but has a custom Term instance?

Brandon.


  

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Inheritance and Wrappers

2011-02-01 Thread John Lato

 From: Steffen Schuldenzucker sschuldenzuc...@uni-bonn.de

 On 01/31/2011 08:58 PM, MattMan wrote:
  [...]
 
  data Wrapper a = Wrap a
  instance (Num a) =  AbGroup (Wrapper a) where
add (Wrap i) (Wrap j) = Wrap(i+j)
 
  However, this is clumsy.  Is there something else I can do?  Thanks
 This is the normal approach. You can do funny things with the
 OverlappingInstances extension, but it is probably not what you want.

 The problem is that the compiler only considers the heads of the
 instance declarations when determining which instance to use for a
 specific type. So an instance like this:

   instance (Num a) = AbGroup a where ...

 means: Some type matching 'a' (that is, any type) is an instance of
 'AbGroup' if and only if it is an instance of 'Num'.


I would word this differently.  I would say this instance means: Some type
matching 'a' (that is, any type) is an instance of 'AbGroup'.  It is an
error to use AbGroup methods if 'a' does not have a Num instance in scope.

The important point is that this declares an AbGroup instance for every
type, not just types with Num instances.  Which means that this instance is
much less useful than you would hope.

I would probably use either Henning's approach of separate functions or an
automatic deriving mechanism.  I've never understood why Haskellers are so
averse to writing new instances anyway.

John
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Inheritance and Wrappers

2011-02-01 Thread Ozgur Akgun
On 1 February 2011 11:41, John Lato jwl...@gmail.com wrote:

 The important point is that this declares an AbGroup instance for every
 type, not just types with Num instances.


So, is there a way to declare an AbGroup instance for the types with num
instances only?

Thanks,
Ozgur
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Inheritance and Wrappers

2011-02-01 Thread Stephen Tetley
On 1 February 2011 11:47, Ozgur Akgun ozgurak...@gmail.com wrote:


 So, is there a way to declare an AbGroup instance for the types with num
 instances only?

No - as Henning says its then no more useful than simply a function:

add :: (Num u) = a - a - a
add = (+)

'Overarching instances' i.e. classes with one implementation are a
design flaw, not a virtue [*] so this hypothetical extension isn't
welcome...

{-# LANGUAGE OverarchingInstances #-}


[*] Of course, there might be some valid cases for things in Oleg
Kiselyov's typecast style, but modelling numericals doesn't look like
one of them.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Inheritance and Wrappers

2011-02-01 Thread Ozgur Akgun
OK, what about this as a use case then. I want to create a type class 'Term'
with only one function in it. The function returns a 'termTag' which labels
the *kind* of a value in a DSL.

class Term a where
   termTag :: a - String

A user of this type-class can happily provide an instance without any other
type class requirement. However, I want those types which are instances of
Data to be an instance of Term automatically. On top of that, I don't want
to stop the user from creating a special instance for their data type.

I want to be able to write the following instance to accomplish that:

instance Data t = Term t where
termTag = show . toConstr

And if the user wants to write a more specific instance, they should be
welcome to do so:

instance Term UserDT where
termTag (...) = ...

I am not very much interested in the technical details about how things
currently are, I am more interested in a discussion about why (if?) this
would be considered a *design flaw*?

Best,

On 1 February 2011 12:18, Stephen Tetley stephen.tet...@gmail.com wrote:

 On 1 February 2011 11:47, Ozgur Akgun ozgurak...@gmail.com wrote:

 
  So, is there a way to declare an AbGroup instance for the types with num
  instances only?

 No - as Henning says its then no more useful than simply a function:

 add :: (Num u) = a - a - a
 add = (+)

 'Overarching instances' i.e. classes with one implementation are a
 design flaw, not a virtue [*] so this hypothetical extension isn't
 welcome...

 {-# LANGUAGE OverarchingInstances #-}


 [*] Of course, there might be some valid cases for things in Oleg
 Kiselyov's typecast style, but modelling numericals doesn't look like
 one of them.

 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe




-- 
Ozgur Akgun
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Inheritance and Wrappers

2011-02-01 Thread John Lato
On Tue, Feb 1, 2011 at 11:47 AM, Ozgur Akgun ozgurak...@gmail.com wrote:

 On 1 February 2011 11:41, John Lato jwl...@gmail.com wrote:

 The important point is that this declares an AbGroup instance for every
 type, not just types with Num instances.


 So, is there a way to declare an AbGroup instance for the types with num
 instances only?


Not to my knowledge.

John
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Inheritance and Wrappers

2011-02-01 Thread Daniel Fischer
On Tuesday 01 February 2011 13:45:34, Ozgur Akgun wrote:
 I want to be able to write the following instance to accomplish that:

 instance Data t = Term t where
     termTag = show . toConstr

 And if the user wants to write a more specific instance, they should be
 welcome to do so:

 instance Term UserDT where
     termTag (...) = ...

 I am not very much interested in the technical details about how things
 currently are, I am more interested in a discussion about why (if?) this
 would be considered a *design flaw*?

I think the strongest reason to consider it a design flaw is the current 
implementation, that instance selection doesn't take contexts into account.
Things being as they are, an

instance A a = B a where ...

just isn't very useful. If instance selection took contexts into account, 
such an instance might be useful, but it would still prevent users from 
declaring instances for both classes (without an extension which would have 
much the same problems as OverlappingInstances).


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Inheritance and Wrappers

2011-02-01 Thread Stephen Tetley
On 1 February 2011 12:45, Ozgur Akgun ozgurak...@gmail.com wrote:

 I am not very much interested in the technical details about how things
 currently are, I am more interested in a discussion about why (if?) this
 would be considered a design flaw?

Wanting a general base case + specific exceptional cases is in no way
heinous. However this is somewhat at odds with type-class resolution
as it stands. SYB3 is a one of systems to reconcile the problem.

[By the way, this needs interpreting with a large grain of salt. I
haven't been following the Generics story much recently, so I could be
mis-representing things, nor do I have a particularly sound knowledge
of how GHC resolves overlapping...]

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Inheritance and Wrappers

2011-01-31 Thread MattMan

tldr: Can I make arbitrary instances of one class instantiate another without
using wrappers?

I'm new to Haskell, and am trying to implement some simple typeclasses for
doing algebra.  For example I have type class (simplified for the sake of
argument)

class AbGroup a where
add :: a - a - a

I would like any type instantiating Num to also be an abelian group:

instance (Num a) = AbGroup a where
 add i j = i+j,

but this doesn't compile because a is a variable, not a type constructor(or
something).  The problem is fixed, in a sense, If I introduce a wrapper
class

data Wrapper a = Wrap a
instance (Num a) = AbGroup (Wrapper a) where
 add (Wrap i) (Wrap j) = Wrap(i+j)

However, this is clumsy.  Is there something else I can do?  Thanks!

-- 
View this message in context: 
http://haskell.1045720.n5.nabble.com/Inheritance-and-Wrappers-tp3365126p3365126.html
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Inheritance and Wrappers

2011-01-31 Thread Steffen Schuldenzucker

On 01/31/2011 08:58 PM, MattMan wrote:

[...]

data Wrapper a = Wrap a
instance (Num a) =  AbGroup (Wrapper a) where
  add (Wrap i) (Wrap j) = Wrap(i+j)

However, this is clumsy.  Is there something else I can do?  Thanks
This is the normal approach. You can do funny things with the 
OverlappingInstances extension, but it is probably not what you want.


The problem is that the compiler only considers the heads of the 
instance declarations when determining which instance to use for a 
specific type. So an instance like this:


 instance (Num a) = AbGroup a where ...

means: Some type matching 'a' (that is, any type) is an instance of 
'AbGroup' if and only if it is an instance of 'Num'.


An additional instance like

 instance AbGroup SomeData where ...

would then conflict with the instance above: As 'SomeData' in particular 
matches the type 'a', the compiler does not know which one to choose. 
You could argue that the latter is more specific than the former, so 
the compiler should choose that one. This is exactly what 
OverlappingInstances does, but it can have more, unwanted effects.


You can make your wrapper code less clumsy by deriving some instances 
such as


 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 data Wrapper a = Wrap a deriving (Eq, Ord, Read, Show, Num)

-- Steffen



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Inheritance and Wrappers

2011-01-31 Thread Daniel Fischer
On Monday 31 January 2011 20:58:02, MattMan wrote:
 tldr: Can I make arbitrary instances of one class instantiate another
 without using wrappers?

 I'm new to Haskell, and am trying to implement some simple typeclasses
 for doing algebra.  For example I have type class (simplified for the
 sake of argument)

 class AbGroup a where
 add :: a - a - a

 I would like any type instantiating Num to also be an abelian group:

 instance (Num a) = AbGroup a where
  add i j = i+j,

 but this doesn't compile because a is a variable, not a type
 constructor(or something).  The problem is fixed, in a sense, If I
 introduce a wrapper class

 data Wrapper a = Wrap a
 instance (Num a) = AbGroup (Wrapper a) where
  add (Wrap i) (Wrap j) = Wrap(i+j)

 However, this is clumsy.  Is there something else I can do?  Thanks!

Not really. You could enable the FexibleInstances extension, then your 
first instance would compile. But it would mean 'every type is an instance 
of AbGroup, and if you try to use it with something that isn't also a Num, 
it won't compile, also you can't have any other instances', not what you 
want. You could then also enable OverlappingInstances, which would allow 
you to write other instances, but that extension is widely regarded as 
dangerous (have to confess, I forgot what the dangers were, one was that 
instance selection doesn't always do what you want/expect).

Wrapper instances or specific instances are probably the best way (specific 
instances to be generated by a preprocessor or TH).

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Inheritance and Wrappers

2011-01-31 Thread Brandon S Allbery KF8NH
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On 1/31/11 15:24 , Daniel Fischer wrote:
 want. You could then also enable OverlappingInstances, which would allow 
 you to write other instances, but that extension is widely regarded as 
 dangerous (have to confess, I forgot what the dangers were, one was that 
 instance selection doesn't always do what you want/expect).

Instance selection will still not look at the context, so multiple instances
would complain about needing IncoherentInstances, and if you add *that* then
it does something like taking the first matching instance it finds (again,
ignoring the context completely).

- -- 
brandon s. allbery [linux,solaris,freebsd,perl]  allb...@kf8nh.com
system administrator  [openafs,heimdal,too many hats]  allb...@ece.cmu.edu
electrical and computer engineering, carnegie mellon university  KF8NH
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.11 (Darwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk1HHNMACgkQIn7hlCsL25XFYgCgqLWUoZzYrZO54ydDY9kTa9RT
3VAAn0WgJzeWO5vvO4QP1pkEYL5tzxYB
=+6Pz
-END PGP SIGNATURE-

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Inheritance and Wrappers

2011-01-31 Thread Henning Thielemann


On Mon, 31 Jan 2011, MattMan wrote:


I'm new to Haskell, and am trying to implement some simple typeclasses for
doing algebra.  For example I have type class (simplified for the sake of
argument)

class AbGroup a where
   add :: a - a - a

I would like any type instantiating Num to also be an abelian group:

instance (Num a) = AbGroup a where
add i j = i+j,


If all methods of AbGroup can be defined for all Num types - why do you 
want an AbGroup at all? You could simply write functions with Num 
constraint.


You may be also interested in existing approaches to algebra in Haskell:
  http://www.haskell.org/haskellwiki/Mathematical_prelude_discussion


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Inheritance and Wrappers

2011-01-31 Thread Henning Thielemann


On Mon, 31 Jan 2011, Brandon S Allbery KF8NH wrote:


On 1/31/11 15:24 , Daniel Fischer wrote:

want. You could then also enable OverlappingInstances, which would allow
you to write other instances, but that extension is widely regarded as
dangerous (have to confess, I forgot what the dangers were, one was that
instance selection doesn't always do what you want/expect).


Instance selection will still not look at the context, so multiple instances
would complain about needing IncoherentInstances, and if you add *that* then
it does something like taking the first matching instance it finds (again,
ignoring the context completely).


Since the original poster classified himself as new to Haskell, I'm afraid 
that advanced and dangerous extensions are not the appropriate answer.


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Inheritance and Wrappers

2011-01-31 Thread MattMan

\quote
Henning Thielemann wrote:
 
 If all methods of AbGroup can be defined for all Num types - why do you 
 want an AbGroup at all? You could simply write functions with Num 
 constraint.
 
 

Well, I'd rather not have to implement (*), abs, etc on every abelian group.



You may be also interested in existing approaches to algebra in Haskell:
   http://www.haskell.org/haskellwiki/Mathematical_prelude_discussion



Yes, in fact I am!  Thanks for the suggestion; it seems numeric-prelude
does [most of] the things I want.  Thanks all.
-- 
View this message in context: 
http://haskell.1045720.n5.nabble.com/Inheritance-and-Wrappers-tp3365126p336.html
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe