Making a basic Haskell type an instance of a new typeclass









up vote
8
down vote

favorite
1












Say I'm trying to define a new typeclass in Haskell, and among other things, it must have a + operation:



class Foo a where
(+) :: a -> a -> a


(In practice the typeclass Foo would have more stuff, but let me stop here to keep this minimal.)



Now, I want to make the basic "Integer" type an instance of Foo; and as far as the + operation goes, I just want to keep the usual addition, which is already defined. How do I do that?



Needless to say, the following makes no sense:



instance Foo Integer where
(+) x y = x+y


It loops forever when I ask Haskell to compute 2+3, but I suppose that's to be expected! I also tried putting nothing at all:



instance Foo Integer


This compiles, but then when I ask for 2+3 I get "No instance nor default method for class operation +". Again, it makes sense...



But how do we do that then?



I guess it's a general question "about the namespace", I mean, when two typeclasses use the same names, what happens? In my case, I get issues when trying to make a type (Integer) an instance of two typeclasses with such a name clash (Num and Foo).



From reading this question, I'm now afraid that what I'm asking for is just prohibited...










share|improve this question























  • I'm realizing that I could do this within a module, with "import qualified Prelude" at the start, and then "instance Foo Prelude.Integer where (+) x y = x Prelude.+ y" or something... right? and then if I import my newly created module, does it all work? how does Haskell understand "2+3" ?
    – Pierre
    Aug 23 at 15:58







  • 5




    Right, I think you're barking up the wrong tree. As you mentioned -- you could ìmport qualified Prelude` and write every addition symbol as Prelude.+, but that seems...wildly unnecessary. Why does Foo have to use the + operator? If you simply change it to something unique, all this craziness goes away :)
    – Adam Smith
    Aug 23 at 16:07










  • @Adam: to take a very mathematical example (but i am, after all, a working mathematician...), you could imagine that Foo is really called AbelianGroup, so that the elements of a type of this class can be added, but NOT multiplied, so they don't belong to Num. Yet it is very natural to use + and not some other symbol... while elements of type "Integer" are certainly examples, among others.
    – Pierre
    Aug 23 at 16:23






  • 1




    PS you could rephrase my question as: how do you define a weaker version of Num, or of any typeclass, where some functions are not defined?
    – Pierre
    Aug 23 at 16:25






  • 2




    There is hackage.haskell.org/package/groups-0.4.1.0/docs/Data-Group.html, which builds groups and abelian groups on top of monoid, using the <> operator. Also- Num has no superclasses (it doesn't require Show or Eq)
    – Samuel Barr
    Aug 23 at 17:00














up vote
8
down vote

favorite
1












Say I'm trying to define a new typeclass in Haskell, and among other things, it must have a + operation:



class Foo a where
(+) :: a -> a -> a


(In practice the typeclass Foo would have more stuff, but let me stop here to keep this minimal.)



Now, I want to make the basic "Integer" type an instance of Foo; and as far as the + operation goes, I just want to keep the usual addition, which is already defined. How do I do that?



Needless to say, the following makes no sense:



instance Foo Integer where
(+) x y = x+y


It loops forever when I ask Haskell to compute 2+3, but I suppose that's to be expected! I also tried putting nothing at all:



instance Foo Integer


This compiles, but then when I ask for 2+3 I get "No instance nor default method for class operation +". Again, it makes sense...



But how do we do that then?



I guess it's a general question "about the namespace", I mean, when two typeclasses use the same names, what happens? In my case, I get issues when trying to make a type (Integer) an instance of two typeclasses with such a name clash (Num and Foo).



From reading this question, I'm now afraid that what I'm asking for is just prohibited...










share|improve this question























  • I'm realizing that I could do this within a module, with "import qualified Prelude" at the start, and then "instance Foo Prelude.Integer where (+) x y = x Prelude.+ y" or something... right? and then if I import my newly created module, does it all work? how does Haskell understand "2+3" ?
    – Pierre
    Aug 23 at 15:58







  • 5




    Right, I think you're barking up the wrong tree. As you mentioned -- you could ìmport qualified Prelude` and write every addition symbol as Prelude.+, but that seems...wildly unnecessary. Why does Foo have to use the + operator? If you simply change it to something unique, all this craziness goes away :)
    – Adam Smith
    Aug 23 at 16:07










  • @Adam: to take a very mathematical example (but i am, after all, a working mathematician...), you could imagine that Foo is really called AbelianGroup, so that the elements of a type of this class can be added, but NOT multiplied, so they don't belong to Num. Yet it is very natural to use + and not some other symbol... while elements of type "Integer" are certainly examples, among others.
    – Pierre
    Aug 23 at 16:23






  • 1




    PS you could rephrase my question as: how do you define a weaker version of Num, or of any typeclass, where some functions are not defined?
    – Pierre
    Aug 23 at 16:25






  • 2




    There is hackage.haskell.org/package/groups-0.4.1.0/docs/Data-Group.html, which builds groups and abelian groups on top of monoid, using the <> operator. Also- Num has no superclasses (it doesn't require Show or Eq)
    – Samuel Barr
    Aug 23 at 17:00












up vote
8
down vote

favorite
1









up vote
8
down vote

favorite
1






1





Say I'm trying to define a new typeclass in Haskell, and among other things, it must have a + operation:



class Foo a where
(+) :: a -> a -> a


(In practice the typeclass Foo would have more stuff, but let me stop here to keep this minimal.)



Now, I want to make the basic "Integer" type an instance of Foo; and as far as the + operation goes, I just want to keep the usual addition, which is already defined. How do I do that?



Needless to say, the following makes no sense:



instance Foo Integer where
(+) x y = x+y


It loops forever when I ask Haskell to compute 2+3, but I suppose that's to be expected! I also tried putting nothing at all:



instance Foo Integer


This compiles, but then when I ask for 2+3 I get "No instance nor default method for class operation +". Again, it makes sense...



But how do we do that then?



I guess it's a general question "about the namespace", I mean, when two typeclasses use the same names, what happens? In my case, I get issues when trying to make a type (Integer) an instance of two typeclasses with such a name clash (Num and Foo).



From reading this question, I'm now afraid that what I'm asking for is just prohibited...










share|improve this question















Say I'm trying to define a new typeclass in Haskell, and among other things, it must have a + operation:



class Foo a where
(+) :: a -> a -> a


(In practice the typeclass Foo would have more stuff, but let me stop here to keep this minimal.)



Now, I want to make the basic "Integer" type an instance of Foo; and as far as the + operation goes, I just want to keep the usual addition, which is already defined. How do I do that?



Needless to say, the following makes no sense:



instance Foo Integer where
(+) x y = x+y


It loops forever when I ask Haskell to compute 2+3, but I suppose that's to be expected! I also tried putting nothing at all:



instance Foo Integer


This compiles, but then when I ask for 2+3 I get "No instance nor default method for class operation +". Again, it makes sense...



But how do we do that then?



I guess it's a general question "about the namespace", I mean, when two typeclasses use the same names, what happens? In my case, I get issues when trying to make a type (Integer) an instance of two typeclasses with such a name clash (Num and Foo).



From reading this question, I'm now afraid that what I'm asking for is just prohibited...







haskell






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Aug 23 at 21:25









Peter Mortensen

13.4k1983111




13.4k1983111










asked Aug 23 at 15:49









Pierre

1485




1485











  • I'm realizing that I could do this within a module, with "import qualified Prelude" at the start, and then "instance Foo Prelude.Integer where (+) x y = x Prelude.+ y" or something... right? and then if I import my newly created module, does it all work? how does Haskell understand "2+3" ?
    – Pierre
    Aug 23 at 15:58







  • 5




    Right, I think you're barking up the wrong tree. As you mentioned -- you could ìmport qualified Prelude` and write every addition symbol as Prelude.+, but that seems...wildly unnecessary. Why does Foo have to use the + operator? If you simply change it to something unique, all this craziness goes away :)
    – Adam Smith
    Aug 23 at 16:07










  • @Adam: to take a very mathematical example (but i am, after all, a working mathematician...), you could imagine that Foo is really called AbelianGroup, so that the elements of a type of this class can be added, but NOT multiplied, so they don't belong to Num. Yet it is very natural to use + and not some other symbol... while elements of type "Integer" are certainly examples, among others.
    – Pierre
    Aug 23 at 16:23






  • 1




    PS you could rephrase my question as: how do you define a weaker version of Num, or of any typeclass, where some functions are not defined?
    – Pierre
    Aug 23 at 16:25






  • 2




    There is hackage.haskell.org/package/groups-0.4.1.0/docs/Data-Group.html, which builds groups and abelian groups on top of monoid, using the <> operator. Also- Num has no superclasses (it doesn't require Show or Eq)
    – Samuel Barr
    Aug 23 at 17:00
















  • I'm realizing that I could do this within a module, with "import qualified Prelude" at the start, and then "instance Foo Prelude.Integer where (+) x y = x Prelude.+ y" or something... right? and then if I import my newly created module, does it all work? how does Haskell understand "2+3" ?
    – Pierre
    Aug 23 at 15:58







  • 5




    Right, I think you're barking up the wrong tree. As you mentioned -- you could ìmport qualified Prelude` and write every addition symbol as Prelude.+, but that seems...wildly unnecessary. Why does Foo have to use the + operator? If you simply change it to something unique, all this craziness goes away :)
    – Adam Smith
    Aug 23 at 16:07










  • @Adam: to take a very mathematical example (but i am, after all, a working mathematician...), you could imagine that Foo is really called AbelianGroup, so that the elements of a type of this class can be added, but NOT multiplied, so they don't belong to Num. Yet it is very natural to use + and not some other symbol... while elements of type "Integer" are certainly examples, among others.
    – Pierre
    Aug 23 at 16:23






  • 1




    PS you could rephrase my question as: how do you define a weaker version of Num, or of any typeclass, where some functions are not defined?
    – Pierre
    Aug 23 at 16:25






  • 2




    There is hackage.haskell.org/package/groups-0.4.1.0/docs/Data-Group.html, which builds groups and abelian groups on top of monoid, using the <> operator. Also- Num has no superclasses (it doesn't require Show or Eq)
    – Samuel Barr
    Aug 23 at 17:00















I'm realizing that I could do this within a module, with "import qualified Prelude" at the start, and then "instance Foo Prelude.Integer where (+) x y = x Prelude.+ y" or something... right? and then if I import my newly created module, does it all work? how does Haskell understand "2+3" ?
– Pierre
Aug 23 at 15:58





I'm realizing that I could do this within a module, with "import qualified Prelude" at the start, and then "instance Foo Prelude.Integer where (+) x y = x Prelude.+ y" or something... right? and then if I import my newly created module, does it all work? how does Haskell understand "2+3" ?
– Pierre
Aug 23 at 15:58





5




5




Right, I think you're barking up the wrong tree. As you mentioned -- you could ìmport qualified Prelude` and write every addition symbol as Prelude.+, but that seems...wildly unnecessary. Why does Foo have to use the + operator? If you simply change it to something unique, all this craziness goes away :)
– Adam Smith
Aug 23 at 16:07




Right, I think you're barking up the wrong tree. As you mentioned -- you could ìmport qualified Prelude` and write every addition symbol as Prelude.+, but that seems...wildly unnecessary. Why does Foo have to use the + operator? If you simply change it to something unique, all this craziness goes away :)
– Adam Smith
Aug 23 at 16:07












@Adam: to take a very mathematical example (but i am, after all, a working mathematician...), you could imagine that Foo is really called AbelianGroup, so that the elements of a type of this class can be added, but NOT multiplied, so they don't belong to Num. Yet it is very natural to use + and not some other symbol... while elements of type "Integer" are certainly examples, among others.
– Pierre
Aug 23 at 16:23




@Adam: to take a very mathematical example (but i am, after all, a working mathematician...), you could imagine that Foo is really called AbelianGroup, so that the elements of a type of this class can be added, but NOT multiplied, so they don't belong to Num. Yet it is very natural to use + and not some other symbol... while elements of type "Integer" are certainly examples, among others.
– Pierre
Aug 23 at 16:23




1




1




PS you could rephrase my question as: how do you define a weaker version of Num, or of any typeclass, where some functions are not defined?
– Pierre
Aug 23 at 16:25




PS you could rephrase my question as: how do you define a weaker version of Num, or of any typeclass, where some functions are not defined?
– Pierre
Aug 23 at 16:25




2




2




There is hackage.haskell.org/package/groups-0.4.1.0/docs/Data-Group.html, which builds groups and abelian groups on top of monoid, using the <> operator. Also- Num has no superclasses (it doesn't require Show or Eq)
– Samuel Barr
Aug 23 at 17:00




There is hackage.haskell.org/package/groups-0.4.1.0/docs/Data-Group.html, which builds groups and abelian groups on top of monoid, using the <> operator. Also- Num has no superclasses (it doesn't require Show or Eq)
– Samuel Barr
Aug 23 at 17:00












6 Answers
6






active

oldest

votes

















up vote
4
down vote



accepted










If you really want to call your operation +, and you want to define it in terms of the + from Prelude, you can do it like this:



import Prelude (Integer, print)
import qualified Prelude ((+))

class Foo a where
(+) :: a -> a -> a

instance Foo Integer where
(+) x y = x Prelude.+ y

main = print (2 + 3 :: Integer)


This will output 5.



To prove that the definition of main is really using our new + operator and not the original one, we can change our definition of +:



import Prelude (Integer, print)
import qualified Prelude ((+))

class Foo a where
(+) :: a -> a -> a

instance Foo Integer where
(+) x y = x Prelude.+ y Prelude.+ 1

main = print (2 + 3 :: Integer)


This will output 6.






share|improve this answer




















  • As you can see from the comments, this is what I had eventually in mind. Because this is definitely the right answer to my specific question, I'll accept it.
    – Pierre
    Aug 24 at 7:31

















up vote
8
down vote













To give a specific solution, something like this would work without having to deal with clashing with (+):



class Foo a where
(<+>) :: a -> a -> a

infixl 6 <+>

instance Foo Integer where
(<+>) = (+)


Now your class Foo has its own operator, and the fixity declaration means that (<+>) will be parsed the same way as (+).






share|improve this answer




















  • "parsed the same way as (+)", in what sense is it the same way? (do you just mean "with the same associativity properties" ?) Anyway, I really need (want...) to use +...
    – Pierre
    Aug 23 at 16:31










  • "infixl 6" means that (<+>) is left associative with a precedence of 6 (in haskell, operators can have a precedence from 0-9, with 0 being lowest and 9 being highest). Left associative means that if you have an expression 1 <+> 2 <+> 3 <+> 4 it will be parsed as (((1 <+> 2) <+> 3) <+> 4); the operations will be performed from left to right. This is the same way (+) behaves.
    – Samuel Barr
    Aug 23 at 16:35


















up vote
2
down vote













I don't think you'd do this the same way in Haskell as in a pure math setting. You're trying to implement an Abelian group (it seems from your comments), which I understand (as someone who hasn't taken a mathematics course since High School) to be a group of type a where there exists a function f :: a -> a -> a such that f x y = f y x.



Contrast that with Haskells built-in (and oft-used) Monoid class and you'll see why I say Haskellers may approach this differently. Monoids are a group of type a where there exists a function f :: a -> a -> a such that f x (f y z) = f (f x y) z (and additionally, but unrelated, a value k such that f x k = x). It's representing associativity rather than commutativity, but is otherwise identical.



Monoids are represented as such:



class Monoid a where
mempty :: a
mappend :: a -> a -> a
mconcat :: [a] -> a


and several are defined, like Sum



newtype Sum a = Sum getSum :: a 
instance Num a => Monoid (Sum a) where
mempty = 0
mappend (Sum x) (Sum y) = Sum (x+y)
-- mconcat is defined as `foldr mappend mempty`


Note that it doesn't try to redefine (+) here. In fact it defines its own operator as a synonym for mappend: (<>). I recommend using a similar syntax with your Abelian group.



class Abelian a where
(|<>|) :: a -> a -> a -- or similar





share|improve this answer



























    up vote
    1
    down vote













    As others have answered, the easiest option is to pick a new name for the operator. This is the approach that most existing packages take, so that users of the library can continue using Num as usual.



    As the OP notes in the comments, it is also possible to import Prelude qualified, and define + however you want. Any other modules that want to use your new + will need to do the same. They can either not import Prelude (via import Prelude () or NoImplicitPrelude), or import it qualified. This is pretty reasonable in a large codebase, where everyone knows the local convention and you can provide instances for all the types you use.






    share|improve this answer



























      up vote
      1
      down vote













      In Haskell, you can use your own Prelude instead of the standard one, and there are multiple existing alternative preludes. E.g. numeric-prelude defines (+) in Algebra.Additive.C.






      share|improve this answer




















      • absolutely! NumericPrelude seems great. But I was wondering if you could achieve some of its functionality in an elementary way (re-writing the Prelude is far beyond what I can personally do, and at the same time, I'd like to understand what I use, in this case).
        – Pierre
        Aug 24 at 7:30

















      up vote
      1
      down vote













      a programmer's approach   As others have said, it is probably best if you forfeit the convenient notation for additive and multiplicative monoids that is widely used in the mathematics community, and rather think of monoid in a more abstract fashion — as a distinct algebraic structure with a distinct operation that, generally, has nothing to do with addition and multiplication in number rings, of which the Num typeclass may be considered an approximate formalization. The Haskell type system is relying on you to make sure that same names refer to same things, and distinct names refer to distinct ones — this simple and logical rule helps it avoid confusion. This is why the monoidal operation of any monoid is usually referred to with a lozenge <> sign. (Actually, the operation on initial monoids is sometimes denoted ++, because of tradition.)



      It is also somewhat illogical, but considered practical, that Num for usual numbers is defined first (and even on the hardware level), and the constituting monoids are extracted afterwards:



      base-4.11.1.0:Data.Semigroup.Internal



      ...
      198 instance Num a => Semigroup (Sum a) where
      199 (<>) = coerce ((+) :: a -> a -> a)
      ...
      227 instance Num a => Semigroup (Product a) where
      228 (<>) = coerce ((*) :: a -> a -> a)
      ...


      — So it happens that + gets occupied long before any abstract algebra comes into play.



       



      an algebraist's approach   Nevertheless, it is very much possible to define a ring out of a type with two monoids:



      -# language FlexibleInstances #-
      -# language FlexibleContexts #-
      -# language UndecidableInstances #-
      -# language TypeApplications #-

      module MonoidsField where

      import Prelude (Integer, Semigroup, (<>), Monoid, mempty, Show, show)
      import Data.Coerce

      newtype Sum a = Sum getSum :: a

      newtype Product a = Product getProduct :: a

      data N = Z | S predecessor :: N

      -- | Substract one; decrease.
      dec :: Coercible a (N -> N) => a
      dec = coerce predecessor

      instance Show N
      where
      show Z = ""
      show x = '|' : show (predecessor x)

      instance Semigroup (Sum N)
      where
      u <> (Sum Z) = u
      u <> v = coerce S (u <> dec v)

      instance Monoid (Sum N)
      where
      mempty = Sum Z

      instance Semigroup (Product N)
      where
      u <> (Product Z) = coerce (mempty @(Sum N))
      u <> v = let (*) = (<>) @(Product N)
      (+) = coerce ((<>) @(Sum N))
      in u + (u * dec v)

      instance Monoid (Product N)
      where
      mempty = Product (S Z)

      (+) :: Monoid (Sum a) => a -> a -> a
      x + y = getSum (Sum x <> Sum y)

      (*) :: Monoid (Product a) => a -> a -> a
      x * y = getProduct (Product x <> Product y)

      class PseudoRing a

      instance (Monoid (Sum a), Monoid (Product a)) => PseudoRing a
      where
      -- You may add some functions that make use of distributivity between the additive and
      -- multiplicative monoid.

      -- ^
      -- λ (S (S (S Z))) + (S (S Z))
      -- |||||
      -- λ (S (S (S Z))) * (S (S Z))
      -- ||||||


      — As you see, the PseudoRing class does not add any operations by itself, but it does make sure that the two monoids it requires are defined. If you instantiate it, it is implied that you have ensured that the axiom of distribution holds.



      As this example suggests, a subclass may be thought of as including in itself all the operations defined for its superclasses. So, it is a possibility that you proclaim instance Num a => Foo a and get to re-use the definition of +. You may then go as far as to define "partial" instances of Num for your own types that a priory will not have a definition for all the required methods. This approach is obviously unsafe, confusing and overall not advisable, but it may be just what you need, especially if decorated with an appropriate scientific license. So, your example becomes:



      class Foo a

      instance Num a => Foo a


       




      Let me know if any of the above requires clarification!






      share|improve this answer






















      • Thanks, very interesting. By the way, ultimately my solution will be to use -XRebindableSyntax. Not only does this NOT load the prelude, so I'll get rid of Num entirely; but also, one can now redefine fromInteger (to be of type Integer -> Integer and equal to Prelude.id), so that literals are interpreted as "Integer" and not Num a => a. So Num is entirely gone from my life, and there are now plenty of available solutions.
        – Pierre
        Aug 28 at 8:57










      • @Pierre Would the source code be available? I am keen on taking a look.
        – Ignat Insarov
        Aug 28 at 15:17










      • just use -# LANGUAGE RebindableSyntax #-followed by import qualified Prelude and then fromInteger :: Integer -> Integer with finally fromInteger = Prelude.id. Then as in the accepted answer, for example (or whatever else you want to do without Num!). I found the trick as an answer to a question on this site :-)
        – Pierre
        Aug 29 at 22:33











      Your Answer






      StackExchange.ifUsing("editor", function ()
      StackExchange.using("externalEditor", function ()
      StackExchange.using("snippets", function ()
      StackExchange.snippets.init();
      );
      );
      , "code-snippets");

      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "1"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













      draft saved

      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f51989707%2fmaking-a-basic-haskell-type-an-instance-of-a-new-typeclass%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      6 Answers
      6






      active

      oldest

      votes








      6 Answers
      6






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      4
      down vote



      accepted










      If you really want to call your operation +, and you want to define it in terms of the + from Prelude, you can do it like this:



      import Prelude (Integer, print)
      import qualified Prelude ((+))

      class Foo a where
      (+) :: a -> a -> a

      instance Foo Integer where
      (+) x y = x Prelude.+ y

      main = print (2 + 3 :: Integer)


      This will output 5.



      To prove that the definition of main is really using our new + operator and not the original one, we can change our definition of +:



      import Prelude (Integer, print)
      import qualified Prelude ((+))

      class Foo a where
      (+) :: a -> a -> a

      instance Foo Integer where
      (+) x y = x Prelude.+ y Prelude.+ 1

      main = print (2 + 3 :: Integer)


      This will output 6.






      share|improve this answer




















      • As you can see from the comments, this is what I had eventually in mind. Because this is definitely the right answer to my specific question, I'll accept it.
        – Pierre
        Aug 24 at 7:31














      up vote
      4
      down vote



      accepted










      If you really want to call your operation +, and you want to define it in terms of the + from Prelude, you can do it like this:



      import Prelude (Integer, print)
      import qualified Prelude ((+))

      class Foo a where
      (+) :: a -> a -> a

      instance Foo Integer where
      (+) x y = x Prelude.+ y

      main = print (2 + 3 :: Integer)


      This will output 5.



      To prove that the definition of main is really using our new + operator and not the original one, we can change our definition of +:



      import Prelude (Integer, print)
      import qualified Prelude ((+))

      class Foo a where
      (+) :: a -> a -> a

      instance Foo Integer where
      (+) x y = x Prelude.+ y Prelude.+ 1

      main = print (2 + 3 :: Integer)


      This will output 6.






      share|improve this answer




















      • As you can see from the comments, this is what I had eventually in mind. Because this is definitely the right answer to my specific question, I'll accept it.
        – Pierre
        Aug 24 at 7:31












      up vote
      4
      down vote



      accepted







      up vote
      4
      down vote



      accepted






      If you really want to call your operation +, and you want to define it in terms of the + from Prelude, you can do it like this:



      import Prelude (Integer, print)
      import qualified Prelude ((+))

      class Foo a where
      (+) :: a -> a -> a

      instance Foo Integer where
      (+) x y = x Prelude.+ y

      main = print (2 + 3 :: Integer)


      This will output 5.



      To prove that the definition of main is really using our new + operator and not the original one, we can change our definition of +:



      import Prelude (Integer, print)
      import qualified Prelude ((+))

      class Foo a where
      (+) :: a -> a -> a

      instance Foo Integer where
      (+) x y = x Prelude.+ y Prelude.+ 1

      main = print (2 + 3 :: Integer)


      This will output 6.






      share|improve this answer












      If you really want to call your operation +, and you want to define it in terms of the + from Prelude, you can do it like this:



      import Prelude (Integer, print)
      import qualified Prelude ((+))

      class Foo a where
      (+) :: a -> a -> a

      instance Foo Integer where
      (+) x y = x Prelude.+ y

      main = print (2 + 3 :: Integer)


      This will output 5.



      To prove that the definition of main is really using our new + operator and not the original one, we can change our definition of +:



      import Prelude (Integer, print)
      import qualified Prelude ((+))

      class Foo a where
      (+) :: a -> a -> a

      instance Foo Integer where
      (+) x y = x Prelude.+ y Prelude.+ 1

      main = print (2 + 3 :: Integer)


      This will output 6.







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Aug 23 at 21:38









      Tanner Swett

      1,5411325




      1,5411325











      • As you can see from the comments, this is what I had eventually in mind. Because this is definitely the right answer to my specific question, I'll accept it.
        – Pierre
        Aug 24 at 7:31
















      • As you can see from the comments, this is what I had eventually in mind. Because this is definitely the right answer to my specific question, I'll accept it.
        – Pierre
        Aug 24 at 7:31















      As you can see from the comments, this is what I had eventually in mind. Because this is definitely the right answer to my specific question, I'll accept it.
      – Pierre
      Aug 24 at 7:31




      As you can see from the comments, this is what I had eventually in mind. Because this is definitely the right answer to my specific question, I'll accept it.
      – Pierre
      Aug 24 at 7:31












      up vote
      8
      down vote













      To give a specific solution, something like this would work without having to deal with clashing with (+):



      class Foo a where
      (<+>) :: a -> a -> a

      infixl 6 <+>

      instance Foo Integer where
      (<+>) = (+)


      Now your class Foo has its own operator, and the fixity declaration means that (<+>) will be parsed the same way as (+).






      share|improve this answer




















      • "parsed the same way as (+)", in what sense is it the same way? (do you just mean "with the same associativity properties" ?) Anyway, I really need (want...) to use +...
        – Pierre
        Aug 23 at 16:31










      • "infixl 6" means that (<+>) is left associative with a precedence of 6 (in haskell, operators can have a precedence from 0-9, with 0 being lowest and 9 being highest). Left associative means that if you have an expression 1 <+> 2 <+> 3 <+> 4 it will be parsed as (((1 <+> 2) <+> 3) <+> 4); the operations will be performed from left to right. This is the same way (+) behaves.
        – Samuel Barr
        Aug 23 at 16:35















      up vote
      8
      down vote













      To give a specific solution, something like this would work without having to deal with clashing with (+):



      class Foo a where
      (<+>) :: a -> a -> a

      infixl 6 <+>

      instance Foo Integer where
      (<+>) = (+)


      Now your class Foo has its own operator, and the fixity declaration means that (<+>) will be parsed the same way as (+).






      share|improve this answer




















      • "parsed the same way as (+)", in what sense is it the same way? (do you just mean "with the same associativity properties" ?) Anyway, I really need (want...) to use +...
        – Pierre
        Aug 23 at 16:31










      • "infixl 6" means that (<+>) is left associative with a precedence of 6 (in haskell, operators can have a precedence from 0-9, with 0 being lowest and 9 being highest). Left associative means that if you have an expression 1 <+> 2 <+> 3 <+> 4 it will be parsed as (((1 <+> 2) <+> 3) <+> 4); the operations will be performed from left to right. This is the same way (+) behaves.
        – Samuel Barr
        Aug 23 at 16:35













      up vote
      8
      down vote










      up vote
      8
      down vote









      To give a specific solution, something like this would work without having to deal with clashing with (+):



      class Foo a where
      (<+>) :: a -> a -> a

      infixl 6 <+>

      instance Foo Integer where
      (<+>) = (+)


      Now your class Foo has its own operator, and the fixity declaration means that (<+>) will be parsed the same way as (+).






      share|improve this answer












      To give a specific solution, something like this would work without having to deal with clashing with (+):



      class Foo a where
      (<+>) :: a -> a -> a

      infixl 6 <+>

      instance Foo Integer where
      (<+>) = (+)


      Now your class Foo has its own operator, and the fixity declaration means that (<+>) will be parsed the same way as (+).







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Aug 23 at 16:21









      Samuel Barr

      1497




      1497











      • "parsed the same way as (+)", in what sense is it the same way? (do you just mean "with the same associativity properties" ?) Anyway, I really need (want...) to use +...
        – Pierre
        Aug 23 at 16:31










      • "infixl 6" means that (<+>) is left associative with a precedence of 6 (in haskell, operators can have a precedence from 0-9, with 0 being lowest and 9 being highest). Left associative means that if you have an expression 1 <+> 2 <+> 3 <+> 4 it will be parsed as (((1 <+> 2) <+> 3) <+> 4); the operations will be performed from left to right. This is the same way (+) behaves.
        – Samuel Barr
        Aug 23 at 16:35

















      • "parsed the same way as (+)", in what sense is it the same way? (do you just mean "with the same associativity properties" ?) Anyway, I really need (want...) to use +...
        – Pierre
        Aug 23 at 16:31










      • "infixl 6" means that (<+>) is left associative with a precedence of 6 (in haskell, operators can have a precedence from 0-9, with 0 being lowest and 9 being highest). Left associative means that if you have an expression 1 <+> 2 <+> 3 <+> 4 it will be parsed as (((1 <+> 2) <+> 3) <+> 4); the operations will be performed from left to right. This is the same way (+) behaves.
        – Samuel Barr
        Aug 23 at 16:35
















      "parsed the same way as (+)", in what sense is it the same way? (do you just mean "with the same associativity properties" ?) Anyway, I really need (want...) to use +...
      – Pierre
      Aug 23 at 16:31




      "parsed the same way as (+)", in what sense is it the same way? (do you just mean "with the same associativity properties" ?) Anyway, I really need (want...) to use +...
      – Pierre
      Aug 23 at 16:31












      "infixl 6" means that (<+>) is left associative with a precedence of 6 (in haskell, operators can have a precedence from 0-9, with 0 being lowest and 9 being highest). Left associative means that if you have an expression 1 <+> 2 <+> 3 <+> 4 it will be parsed as (((1 <+> 2) <+> 3) <+> 4); the operations will be performed from left to right. This is the same way (+) behaves.
      – Samuel Barr
      Aug 23 at 16:35





      "infixl 6" means that (<+>) is left associative with a precedence of 6 (in haskell, operators can have a precedence from 0-9, with 0 being lowest and 9 being highest). Left associative means that if you have an expression 1 <+> 2 <+> 3 <+> 4 it will be parsed as (((1 <+> 2) <+> 3) <+> 4); the operations will be performed from left to right. This is the same way (+) behaves.
      – Samuel Barr
      Aug 23 at 16:35











      up vote
      2
      down vote













      I don't think you'd do this the same way in Haskell as in a pure math setting. You're trying to implement an Abelian group (it seems from your comments), which I understand (as someone who hasn't taken a mathematics course since High School) to be a group of type a where there exists a function f :: a -> a -> a such that f x y = f y x.



      Contrast that with Haskells built-in (and oft-used) Monoid class and you'll see why I say Haskellers may approach this differently. Monoids are a group of type a where there exists a function f :: a -> a -> a such that f x (f y z) = f (f x y) z (and additionally, but unrelated, a value k such that f x k = x). It's representing associativity rather than commutativity, but is otherwise identical.



      Monoids are represented as such:



      class Monoid a where
      mempty :: a
      mappend :: a -> a -> a
      mconcat :: [a] -> a


      and several are defined, like Sum



      newtype Sum a = Sum getSum :: a 
      instance Num a => Monoid (Sum a) where
      mempty = 0
      mappend (Sum x) (Sum y) = Sum (x+y)
      -- mconcat is defined as `foldr mappend mempty`


      Note that it doesn't try to redefine (+) here. In fact it defines its own operator as a synonym for mappend: (<>). I recommend using a similar syntax with your Abelian group.



      class Abelian a where
      (|<>|) :: a -> a -> a -- or similar





      share|improve this answer
























        up vote
        2
        down vote













        I don't think you'd do this the same way in Haskell as in a pure math setting. You're trying to implement an Abelian group (it seems from your comments), which I understand (as someone who hasn't taken a mathematics course since High School) to be a group of type a where there exists a function f :: a -> a -> a such that f x y = f y x.



        Contrast that with Haskells built-in (and oft-used) Monoid class and you'll see why I say Haskellers may approach this differently. Monoids are a group of type a where there exists a function f :: a -> a -> a such that f x (f y z) = f (f x y) z (and additionally, but unrelated, a value k such that f x k = x). It's representing associativity rather than commutativity, but is otherwise identical.



        Monoids are represented as such:



        class Monoid a where
        mempty :: a
        mappend :: a -> a -> a
        mconcat :: [a] -> a


        and several are defined, like Sum



        newtype Sum a = Sum getSum :: a 
        instance Num a => Monoid (Sum a) where
        mempty = 0
        mappend (Sum x) (Sum y) = Sum (x+y)
        -- mconcat is defined as `foldr mappend mempty`


        Note that it doesn't try to redefine (+) here. In fact it defines its own operator as a synonym for mappend: (<>). I recommend using a similar syntax with your Abelian group.



        class Abelian a where
        (|<>|) :: a -> a -> a -- or similar





        share|improve this answer






















          up vote
          2
          down vote










          up vote
          2
          down vote









          I don't think you'd do this the same way in Haskell as in a pure math setting. You're trying to implement an Abelian group (it seems from your comments), which I understand (as someone who hasn't taken a mathematics course since High School) to be a group of type a where there exists a function f :: a -> a -> a such that f x y = f y x.



          Contrast that with Haskells built-in (and oft-used) Monoid class and you'll see why I say Haskellers may approach this differently. Monoids are a group of type a where there exists a function f :: a -> a -> a such that f x (f y z) = f (f x y) z (and additionally, but unrelated, a value k such that f x k = x). It's representing associativity rather than commutativity, but is otherwise identical.



          Monoids are represented as such:



          class Monoid a where
          mempty :: a
          mappend :: a -> a -> a
          mconcat :: [a] -> a


          and several are defined, like Sum



          newtype Sum a = Sum getSum :: a 
          instance Num a => Monoid (Sum a) where
          mempty = 0
          mappend (Sum x) (Sum y) = Sum (x+y)
          -- mconcat is defined as `foldr mappend mempty`


          Note that it doesn't try to redefine (+) here. In fact it defines its own operator as a synonym for mappend: (<>). I recommend using a similar syntax with your Abelian group.



          class Abelian a where
          (|<>|) :: a -> a -> a -- or similar





          share|improve this answer












          I don't think you'd do this the same way in Haskell as in a pure math setting. You're trying to implement an Abelian group (it seems from your comments), which I understand (as someone who hasn't taken a mathematics course since High School) to be a group of type a where there exists a function f :: a -> a -> a such that f x y = f y x.



          Contrast that with Haskells built-in (and oft-used) Monoid class and you'll see why I say Haskellers may approach this differently. Monoids are a group of type a where there exists a function f :: a -> a -> a such that f x (f y z) = f (f x y) z (and additionally, but unrelated, a value k such that f x k = x). It's representing associativity rather than commutativity, but is otherwise identical.



          Monoids are represented as such:



          class Monoid a where
          mempty :: a
          mappend :: a -> a -> a
          mconcat :: [a] -> a


          and several are defined, like Sum



          newtype Sum a = Sum getSum :: a 
          instance Num a => Monoid (Sum a) where
          mempty = 0
          mappend (Sum x) (Sum y) = Sum (x+y)
          -- mconcat is defined as `foldr mappend mempty`


          Note that it doesn't try to redefine (+) here. In fact it defines its own operator as a synonym for mappend: (<>). I recommend using a similar syntax with your Abelian group.



          class Abelian a where
          (|<>|) :: a -> a -> a -- or similar






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Aug 23 at 17:03









          Adam Smith

          32.8k53174




          32.8k53174




















              up vote
              1
              down vote













              As others have answered, the easiest option is to pick a new name for the operator. This is the approach that most existing packages take, so that users of the library can continue using Num as usual.



              As the OP notes in the comments, it is also possible to import Prelude qualified, and define + however you want. Any other modules that want to use your new + will need to do the same. They can either not import Prelude (via import Prelude () or NoImplicitPrelude), or import it qualified. This is pretty reasonable in a large codebase, where everyone knows the local convention and you can provide instances for all the types you use.






              share|improve this answer
























                up vote
                1
                down vote













                As others have answered, the easiest option is to pick a new name for the operator. This is the approach that most existing packages take, so that users of the library can continue using Num as usual.



                As the OP notes in the comments, it is also possible to import Prelude qualified, and define + however you want. Any other modules that want to use your new + will need to do the same. They can either not import Prelude (via import Prelude () or NoImplicitPrelude), or import it qualified. This is pretty reasonable in a large codebase, where everyone knows the local convention and you can provide instances for all the types you use.






                share|improve this answer






















                  up vote
                  1
                  down vote










                  up vote
                  1
                  down vote









                  As others have answered, the easiest option is to pick a new name for the operator. This is the approach that most existing packages take, so that users of the library can continue using Num as usual.



                  As the OP notes in the comments, it is also possible to import Prelude qualified, and define + however you want. Any other modules that want to use your new + will need to do the same. They can either not import Prelude (via import Prelude () or NoImplicitPrelude), or import it qualified. This is pretty reasonable in a large codebase, where everyone knows the local convention and you can provide instances for all the types you use.






                  share|improve this answer












                  As others have answered, the easiest option is to pick a new name for the operator. This is the approach that most existing packages take, so that users of the library can continue using Num as usual.



                  As the OP notes in the comments, it is also possible to import Prelude qualified, and define + however you want. Any other modules that want to use your new + will need to do the same. They can either not import Prelude (via import Prelude () or NoImplicitPrelude), or import it qualified. This is pretty reasonable in a large codebase, where everyone knows the local convention and you can provide instances for all the types you use.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Aug 23 at 17:14









                  bergey

                  2,303515




                  2,303515




















                      up vote
                      1
                      down vote













                      In Haskell, you can use your own Prelude instead of the standard one, and there are multiple existing alternative preludes. E.g. numeric-prelude defines (+) in Algebra.Additive.C.






                      share|improve this answer




















                      • absolutely! NumericPrelude seems great. But I was wondering if you could achieve some of its functionality in an elementary way (re-writing the Prelude is far beyond what I can personally do, and at the same time, I'd like to understand what I use, in this case).
                        – Pierre
                        Aug 24 at 7:30














                      up vote
                      1
                      down vote













                      In Haskell, you can use your own Prelude instead of the standard one, and there are multiple existing alternative preludes. E.g. numeric-prelude defines (+) in Algebra.Additive.C.






                      share|improve this answer




















                      • absolutely! NumericPrelude seems great. But I was wondering if you could achieve some of its functionality in an elementary way (re-writing the Prelude is far beyond what I can personally do, and at the same time, I'd like to understand what I use, in this case).
                        – Pierre
                        Aug 24 at 7:30












                      up vote
                      1
                      down vote










                      up vote
                      1
                      down vote









                      In Haskell, you can use your own Prelude instead of the standard one, and there are multiple existing alternative preludes. E.g. numeric-prelude defines (+) in Algebra.Additive.C.






                      share|improve this answer












                      In Haskell, you can use your own Prelude instead of the standard one, and there are multiple existing alternative preludes. E.g. numeric-prelude defines (+) in Algebra.Additive.C.







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Aug 23 at 19:40









                      Alexey Romanov

                      105k25207348




                      105k25207348











                      • absolutely! NumericPrelude seems great. But I was wondering if you could achieve some of its functionality in an elementary way (re-writing the Prelude is far beyond what I can personally do, and at the same time, I'd like to understand what I use, in this case).
                        – Pierre
                        Aug 24 at 7:30
















                      • absolutely! NumericPrelude seems great. But I was wondering if you could achieve some of its functionality in an elementary way (re-writing the Prelude is far beyond what I can personally do, and at the same time, I'd like to understand what I use, in this case).
                        – Pierre
                        Aug 24 at 7:30















                      absolutely! NumericPrelude seems great. But I was wondering if you could achieve some of its functionality in an elementary way (re-writing the Prelude is far beyond what I can personally do, and at the same time, I'd like to understand what I use, in this case).
                      – Pierre
                      Aug 24 at 7:30




                      absolutely! NumericPrelude seems great. But I was wondering if you could achieve some of its functionality in an elementary way (re-writing the Prelude is far beyond what I can personally do, and at the same time, I'd like to understand what I use, in this case).
                      – Pierre
                      Aug 24 at 7:30










                      up vote
                      1
                      down vote













                      a programmer's approach   As others have said, it is probably best if you forfeit the convenient notation for additive and multiplicative monoids that is widely used in the mathematics community, and rather think of monoid in a more abstract fashion — as a distinct algebraic structure with a distinct operation that, generally, has nothing to do with addition and multiplication in number rings, of which the Num typeclass may be considered an approximate formalization. The Haskell type system is relying on you to make sure that same names refer to same things, and distinct names refer to distinct ones — this simple and logical rule helps it avoid confusion. This is why the monoidal operation of any monoid is usually referred to with a lozenge <> sign. (Actually, the operation on initial monoids is sometimes denoted ++, because of tradition.)



                      It is also somewhat illogical, but considered practical, that Num for usual numbers is defined first (and even on the hardware level), and the constituting monoids are extracted afterwards:



                      base-4.11.1.0:Data.Semigroup.Internal



                      ...
                      198 instance Num a => Semigroup (Sum a) where
                      199 (<>) = coerce ((+) :: a -> a -> a)
                      ...
                      227 instance Num a => Semigroup (Product a) where
                      228 (<>) = coerce ((*) :: a -> a -> a)
                      ...


                      — So it happens that + gets occupied long before any abstract algebra comes into play.



                       



                      an algebraist's approach   Nevertheless, it is very much possible to define a ring out of a type with two monoids:



                      -# language FlexibleInstances #-
                      -# language FlexibleContexts #-
                      -# language UndecidableInstances #-
                      -# language TypeApplications #-

                      module MonoidsField where

                      import Prelude (Integer, Semigroup, (<>), Monoid, mempty, Show, show)
                      import Data.Coerce

                      newtype Sum a = Sum getSum :: a

                      newtype Product a = Product getProduct :: a

                      data N = Z | S predecessor :: N

                      -- | Substract one; decrease.
                      dec :: Coercible a (N -> N) => a
                      dec = coerce predecessor

                      instance Show N
                      where
                      show Z = ""
                      show x = '|' : show (predecessor x)

                      instance Semigroup (Sum N)
                      where
                      u <> (Sum Z) = u
                      u <> v = coerce S (u <> dec v)

                      instance Monoid (Sum N)
                      where
                      mempty = Sum Z

                      instance Semigroup (Product N)
                      where
                      u <> (Product Z) = coerce (mempty @(Sum N))
                      u <> v = let (*) = (<>) @(Product N)
                      (+) = coerce ((<>) @(Sum N))
                      in u + (u * dec v)

                      instance Monoid (Product N)
                      where
                      mempty = Product (S Z)

                      (+) :: Monoid (Sum a) => a -> a -> a
                      x + y = getSum (Sum x <> Sum y)

                      (*) :: Monoid (Product a) => a -> a -> a
                      x * y = getProduct (Product x <> Product y)

                      class PseudoRing a

                      instance (Monoid (Sum a), Monoid (Product a)) => PseudoRing a
                      where
                      -- You may add some functions that make use of distributivity between the additive and
                      -- multiplicative monoid.

                      -- ^
                      -- λ (S (S (S Z))) + (S (S Z))
                      -- |||||
                      -- λ (S (S (S Z))) * (S (S Z))
                      -- ||||||


                      — As you see, the PseudoRing class does not add any operations by itself, but it does make sure that the two monoids it requires are defined. If you instantiate it, it is implied that you have ensured that the axiom of distribution holds.



                      As this example suggests, a subclass may be thought of as including in itself all the operations defined for its superclasses. So, it is a possibility that you proclaim instance Num a => Foo a and get to re-use the definition of +. You may then go as far as to define "partial" instances of Num for your own types that a priory will not have a definition for all the required methods. This approach is obviously unsafe, confusing and overall not advisable, but it may be just what you need, especially if decorated with an appropriate scientific license. So, your example becomes:



                      class Foo a

                      instance Num a => Foo a


                       




                      Let me know if any of the above requires clarification!






                      share|improve this answer






















                      • Thanks, very interesting. By the way, ultimately my solution will be to use -XRebindableSyntax. Not only does this NOT load the prelude, so I'll get rid of Num entirely; but also, one can now redefine fromInteger (to be of type Integer -> Integer and equal to Prelude.id), so that literals are interpreted as "Integer" and not Num a => a. So Num is entirely gone from my life, and there are now plenty of available solutions.
                        – Pierre
                        Aug 28 at 8:57










                      • @Pierre Would the source code be available? I am keen on taking a look.
                        – Ignat Insarov
                        Aug 28 at 15:17










                      • just use -# LANGUAGE RebindableSyntax #-followed by import qualified Prelude and then fromInteger :: Integer -> Integer with finally fromInteger = Prelude.id. Then as in the accepted answer, for example (or whatever else you want to do without Num!). I found the trick as an answer to a question on this site :-)
                        – Pierre
                        Aug 29 at 22:33















                      up vote
                      1
                      down vote













                      a programmer's approach   As others have said, it is probably best if you forfeit the convenient notation for additive and multiplicative monoids that is widely used in the mathematics community, and rather think of monoid in a more abstract fashion — as a distinct algebraic structure with a distinct operation that, generally, has nothing to do with addition and multiplication in number rings, of which the Num typeclass may be considered an approximate formalization. The Haskell type system is relying on you to make sure that same names refer to same things, and distinct names refer to distinct ones — this simple and logical rule helps it avoid confusion. This is why the monoidal operation of any monoid is usually referred to with a lozenge <> sign. (Actually, the operation on initial monoids is sometimes denoted ++, because of tradition.)



                      It is also somewhat illogical, but considered practical, that Num for usual numbers is defined first (and even on the hardware level), and the constituting monoids are extracted afterwards:



                      base-4.11.1.0:Data.Semigroup.Internal



                      ...
                      198 instance Num a => Semigroup (Sum a) where
                      199 (<>) = coerce ((+) :: a -> a -> a)
                      ...
                      227 instance Num a => Semigroup (Product a) where
                      228 (<>) = coerce ((*) :: a -> a -> a)
                      ...


                      — So it happens that + gets occupied long before any abstract algebra comes into play.



                       



                      an algebraist's approach   Nevertheless, it is very much possible to define a ring out of a type with two monoids:



                      -# language FlexibleInstances #-
                      -# language FlexibleContexts #-
                      -# language UndecidableInstances #-
                      -# language TypeApplications #-

                      module MonoidsField where

                      import Prelude (Integer, Semigroup, (<>), Monoid, mempty, Show, show)
                      import Data.Coerce

                      newtype Sum a = Sum getSum :: a

                      newtype Product a = Product getProduct :: a

                      data N = Z | S predecessor :: N

                      -- | Substract one; decrease.
                      dec :: Coercible a (N -> N) => a
                      dec = coerce predecessor

                      instance Show N
                      where
                      show Z = ""
                      show x = '|' : show (predecessor x)

                      instance Semigroup (Sum N)
                      where
                      u <> (Sum Z) = u
                      u <> v = coerce S (u <> dec v)

                      instance Monoid (Sum N)
                      where
                      mempty = Sum Z

                      instance Semigroup (Product N)
                      where
                      u <> (Product Z) = coerce (mempty @(Sum N))
                      u <> v = let (*) = (<>) @(Product N)
                      (+) = coerce ((<>) @(Sum N))
                      in u + (u * dec v)

                      instance Monoid (Product N)
                      where
                      mempty = Product (S Z)

                      (+) :: Monoid (Sum a) => a -> a -> a
                      x + y = getSum (Sum x <> Sum y)

                      (*) :: Monoid (Product a) => a -> a -> a
                      x * y = getProduct (Product x <> Product y)

                      class PseudoRing a

                      instance (Monoid (Sum a), Monoid (Product a)) => PseudoRing a
                      where
                      -- You may add some functions that make use of distributivity between the additive and
                      -- multiplicative monoid.

                      -- ^
                      -- λ (S (S (S Z))) + (S (S Z))
                      -- |||||
                      -- λ (S (S (S Z))) * (S (S Z))
                      -- ||||||


                      — As you see, the PseudoRing class does not add any operations by itself, but it does make sure that the two monoids it requires are defined. If you instantiate it, it is implied that you have ensured that the axiom of distribution holds.



                      As this example suggests, a subclass may be thought of as including in itself all the operations defined for its superclasses. So, it is a possibility that you proclaim instance Num a => Foo a and get to re-use the definition of +. You may then go as far as to define "partial" instances of Num for your own types that a priory will not have a definition for all the required methods. This approach is obviously unsafe, confusing and overall not advisable, but it may be just what you need, especially if decorated with an appropriate scientific license. So, your example becomes:



                      class Foo a

                      instance Num a => Foo a


                       




                      Let me know if any of the above requires clarification!






                      share|improve this answer






















                      • Thanks, very interesting. By the way, ultimately my solution will be to use -XRebindableSyntax. Not only does this NOT load the prelude, so I'll get rid of Num entirely; but also, one can now redefine fromInteger (to be of type Integer -> Integer and equal to Prelude.id), so that literals are interpreted as "Integer" and not Num a => a. So Num is entirely gone from my life, and there are now plenty of available solutions.
                        – Pierre
                        Aug 28 at 8:57










                      • @Pierre Would the source code be available? I am keen on taking a look.
                        – Ignat Insarov
                        Aug 28 at 15:17










                      • just use -# LANGUAGE RebindableSyntax #-followed by import qualified Prelude and then fromInteger :: Integer -> Integer with finally fromInteger = Prelude.id. Then as in the accepted answer, for example (or whatever else you want to do without Num!). I found the trick as an answer to a question on this site :-)
                        – Pierre
                        Aug 29 at 22:33













                      up vote
                      1
                      down vote










                      up vote
                      1
                      down vote









                      a programmer's approach   As others have said, it is probably best if you forfeit the convenient notation for additive and multiplicative monoids that is widely used in the mathematics community, and rather think of monoid in a more abstract fashion — as a distinct algebraic structure with a distinct operation that, generally, has nothing to do with addition and multiplication in number rings, of which the Num typeclass may be considered an approximate formalization. The Haskell type system is relying on you to make sure that same names refer to same things, and distinct names refer to distinct ones — this simple and logical rule helps it avoid confusion. This is why the monoidal operation of any monoid is usually referred to with a lozenge <> sign. (Actually, the operation on initial monoids is sometimes denoted ++, because of tradition.)



                      It is also somewhat illogical, but considered practical, that Num for usual numbers is defined first (and even on the hardware level), and the constituting monoids are extracted afterwards:



                      base-4.11.1.0:Data.Semigroup.Internal



                      ...
                      198 instance Num a => Semigroup (Sum a) where
                      199 (<>) = coerce ((+) :: a -> a -> a)
                      ...
                      227 instance Num a => Semigroup (Product a) where
                      228 (<>) = coerce ((*) :: a -> a -> a)
                      ...


                      — So it happens that + gets occupied long before any abstract algebra comes into play.



                       



                      an algebraist's approach   Nevertheless, it is very much possible to define a ring out of a type with two monoids:



                      -# language FlexibleInstances #-
                      -# language FlexibleContexts #-
                      -# language UndecidableInstances #-
                      -# language TypeApplications #-

                      module MonoidsField where

                      import Prelude (Integer, Semigroup, (<>), Monoid, mempty, Show, show)
                      import Data.Coerce

                      newtype Sum a = Sum getSum :: a

                      newtype Product a = Product getProduct :: a

                      data N = Z | S predecessor :: N

                      -- | Substract one; decrease.
                      dec :: Coercible a (N -> N) => a
                      dec = coerce predecessor

                      instance Show N
                      where
                      show Z = ""
                      show x = '|' : show (predecessor x)

                      instance Semigroup (Sum N)
                      where
                      u <> (Sum Z) = u
                      u <> v = coerce S (u <> dec v)

                      instance Monoid (Sum N)
                      where
                      mempty = Sum Z

                      instance Semigroup (Product N)
                      where
                      u <> (Product Z) = coerce (mempty @(Sum N))
                      u <> v = let (*) = (<>) @(Product N)
                      (+) = coerce ((<>) @(Sum N))
                      in u + (u * dec v)

                      instance Monoid (Product N)
                      where
                      mempty = Product (S Z)

                      (+) :: Monoid (Sum a) => a -> a -> a
                      x + y = getSum (Sum x <> Sum y)

                      (*) :: Monoid (Product a) => a -> a -> a
                      x * y = getProduct (Product x <> Product y)

                      class PseudoRing a

                      instance (Monoid (Sum a), Monoid (Product a)) => PseudoRing a
                      where
                      -- You may add some functions that make use of distributivity between the additive and
                      -- multiplicative monoid.

                      -- ^
                      -- λ (S (S (S Z))) + (S (S Z))
                      -- |||||
                      -- λ (S (S (S Z))) * (S (S Z))
                      -- ||||||


                      — As you see, the PseudoRing class does not add any operations by itself, but it does make sure that the two monoids it requires are defined. If you instantiate it, it is implied that you have ensured that the axiom of distribution holds.



                      As this example suggests, a subclass may be thought of as including in itself all the operations defined for its superclasses. So, it is a possibility that you proclaim instance Num a => Foo a and get to re-use the definition of +. You may then go as far as to define "partial" instances of Num for your own types that a priory will not have a definition for all the required methods. This approach is obviously unsafe, confusing and overall not advisable, but it may be just what you need, especially if decorated with an appropriate scientific license. So, your example becomes:



                      class Foo a

                      instance Num a => Foo a


                       




                      Let me know if any of the above requires clarification!






                      share|improve this answer














                      a programmer's approach   As others have said, it is probably best if you forfeit the convenient notation for additive and multiplicative monoids that is widely used in the mathematics community, and rather think of monoid in a more abstract fashion — as a distinct algebraic structure with a distinct operation that, generally, has nothing to do with addition and multiplication in number rings, of which the Num typeclass may be considered an approximate formalization. The Haskell type system is relying on you to make sure that same names refer to same things, and distinct names refer to distinct ones — this simple and logical rule helps it avoid confusion. This is why the monoidal operation of any monoid is usually referred to with a lozenge <> sign. (Actually, the operation on initial monoids is sometimes denoted ++, because of tradition.)



                      It is also somewhat illogical, but considered practical, that Num for usual numbers is defined first (and even on the hardware level), and the constituting monoids are extracted afterwards:



                      base-4.11.1.0:Data.Semigroup.Internal



                      ...
                      198 instance Num a => Semigroup (Sum a) where
                      199 (<>) = coerce ((+) :: a -> a -> a)
                      ...
                      227 instance Num a => Semigroup (Product a) where
                      228 (<>) = coerce ((*) :: a -> a -> a)
                      ...


                      — So it happens that + gets occupied long before any abstract algebra comes into play.



                       



                      an algebraist's approach   Nevertheless, it is very much possible to define a ring out of a type with two monoids:



                      -# language FlexibleInstances #-
                      -# language FlexibleContexts #-
                      -# language UndecidableInstances #-
                      -# language TypeApplications #-

                      module MonoidsField where

                      import Prelude (Integer, Semigroup, (<>), Monoid, mempty, Show, show)
                      import Data.Coerce

                      newtype Sum a = Sum getSum :: a

                      newtype Product a = Product getProduct :: a

                      data N = Z | S predecessor :: N

                      -- | Substract one; decrease.
                      dec :: Coercible a (N -> N) => a
                      dec = coerce predecessor

                      instance Show N
                      where
                      show Z = ""
                      show x = '|' : show (predecessor x)

                      instance Semigroup (Sum N)
                      where
                      u <> (Sum Z) = u
                      u <> v = coerce S (u <> dec v)

                      instance Monoid (Sum N)
                      where
                      mempty = Sum Z

                      instance Semigroup (Product N)
                      where
                      u <> (Product Z) = coerce (mempty @(Sum N))
                      u <> v = let (*) = (<>) @(Product N)
                      (+) = coerce ((<>) @(Sum N))
                      in u + (u * dec v)

                      instance Monoid (Product N)
                      where
                      mempty = Product (S Z)

                      (+) :: Monoid (Sum a) => a -> a -> a
                      x + y = getSum (Sum x <> Sum y)

                      (*) :: Monoid (Product a) => a -> a -> a
                      x * y = getProduct (Product x <> Product y)

                      class PseudoRing a

                      instance (Monoid (Sum a), Monoid (Product a)) => PseudoRing a
                      where
                      -- You may add some functions that make use of distributivity between the additive and
                      -- multiplicative monoid.

                      -- ^
                      -- λ (S (S (S Z))) + (S (S Z))
                      -- |||||
                      -- λ (S (S (S Z))) * (S (S Z))
                      -- ||||||


                      — As you see, the PseudoRing class does not add any operations by itself, but it does make sure that the two monoids it requires are defined. If you instantiate it, it is implied that you have ensured that the axiom of distribution holds.



                      As this example suggests, a subclass may be thought of as including in itself all the operations defined for its superclasses. So, it is a possibility that you proclaim instance Num a => Foo a and get to re-use the definition of +. You may then go as far as to define "partial" instances of Num for your own types that a priory will not have a definition for all the required methods. This approach is obviously unsafe, confusing and overall not advisable, but it may be just what you need, especially if decorated with an appropriate scientific license. So, your example becomes:



                      class Foo a

                      instance Num a => Foo a


                       




                      Let me know if any of the above requires clarification!







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited Aug 24 at 10:17

























                      answered Aug 24 at 8:42









                      Ignat Insarov

                      1,7501023




                      1,7501023











                      • Thanks, very interesting. By the way, ultimately my solution will be to use -XRebindableSyntax. Not only does this NOT load the prelude, so I'll get rid of Num entirely; but also, one can now redefine fromInteger (to be of type Integer -> Integer and equal to Prelude.id), so that literals are interpreted as "Integer" and not Num a => a. So Num is entirely gone from my life, and there are now plenty of available solutions.
                        – Pierre
                        Aug 28 at 8:57










                      • @Pierre Would the source code be available? I am keen on taking a look.
                        – Ignat Insarov
                        Aug 28 at 15:17










                      • just use -# LANGUAGE RebindableSyntax #-followed by import qualified Prelude and then fromInteger :: Integer -> Integer with finally fromInteger = Prelude.id. Then as in the accepted answer, for example (or whatever else you want to do without Num!). I found the trick as an answer to a question on this site :-)
                        – Pierre
                        Aug 29 at 22:33

















                      • Thanks, very interesting. By the way, ultimately my solution will be to use -XRebindableSyntax. Not only does this NOT load the prelude, so I'll get rid of Num entirely; but also, one can now redefine fromInteger (to be of type Integer -> Integer and equal to Prelude.id), so that literals are interpreted as "Integer" and not Num a => a. So Num is entirely gone from my life, and there are now plenty of available solutions.
                        – Pierre
                        Aug 28 at 8:57










                      • @Pierre Would the source code be available? I am keen on taking a look.
                        – Ignat Insarov
                        Aug 28 at 15:17










                      • just use -# LANGUAGE RebindableSyntax #-followed by import qualified Prelude and then fromInteger :: Integer -> Integer with finally fromInteger = Prelude.id. Then as in the accepted answer, for example (or whatever else you want to do without Num!). I found the trick as an answer to a question on this site :-)
                        – Pierre
                        Aug 29 at 22:33
















                      Thanks, very interesting. By the way, ultimately my solution will be to use -XRebindableSyntax. Not only does this NOT load the prelude, so I'll get rid of Num entirely; but also, one can now redefine fromInteger (to be of type Integer -> Integer and equal to Prelude.id), so that literals are interpreted as "Integer" and not Num a => a. So Num is entirely gone from my life, and there are now plenty of available solutions.
                      – Pierre
                      Aug 28 at 8:57




                      Thanks, very interesting. By the way, ultimately my solution will be to use -XRebindableSyntax. Not only does this NOT load the prelude, so I'll get rid of Num entirely; but also, one can now redefine fromInteger (to be of type Integer -> Integer and equal to Prelude.id), so that literals are interpreted as "Integer" and not Num a => a. So Num is entirely gone from my life, and there are now plenty of available solutions.
                      – Pierre
                      Aug 28 at 8:57












                      @Pierre Would the source code be available? I am keen on taking a look.
                      – Ignat Insarov
                      Aug 28 at 15:17




                      @Pierre Would the source code be available? I am keen on taking a look.
                      – Ignat Insarov
                      Aug 28 at 15:17












                      just use -# LANGUAGE RebindableSyntax #-followed by import qualified Prelude and then fromInteger :: Integer -> Integer with finally fromInteger = Prelude.id. Then as in the accepted answer, for example (or whatever else you want to do without Num!). I found the trick as an answer to a question on this site :-)
                      – Pierre
                      Aug 29 at 22:33





                      just use -# LANGUAGE RebindableSyntax #-followed by import qualified Prelude and then fromInteger :: Integer -> Integer with finally fromInteger = Prelude.id. Then as in the accepted answer, for example (or whatever else you want to do without Num!). I found the trick as an answer to a question on this site :-)
                      – Pierre
                      Aug 29 at 22:33


















                      draft saved

                      draft discarded
















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f51989707%2fmaking-a-basic-haskell-type-an-instance-of-a-new-typeclass%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

                      How do I collapse sections of code in Visual Studio Code for Windows?

                      ャフサォクコ ケウ,コ,ワ メ,ロスョノ゙,クネ,フムカヤヲニ,エコ゚ツ ウイオン゙ケワサネォキモュキォウイノンコチ゚メヌナイゥフュ,カヒウネェ ネ,ホノケ,ムュキ ッボーミュハ,チ ツス ィ メウイマヤ,゙ウチ ヅ ロ,ォジヌェ ャヌット ェ,マャ,チナエヒネソキツテ トホヲヲミーァ