Data.Monoid in the base package specifies newtypes Sum and Product. It would be convenient if these newtypes had appropriate Num instances, which are trivial to write in plain Haskell:<br><br><pre><span class="hs-keyword">import</span> <span class="hs-conid">Data</span><span class="hs-varop">.</span><span class="hs-conid">Monoid</span>

<span class="hs-definition">liftTy2</span> <span class="hs-varid">wrap</span> <span class="hs-varid">unwrap</span> <span class="hs-varid">op</span> <span class="hs-varid">x</span> <span class="hs-varid">y</span> <span class="hs-keyglyph">=</span> <span class="hs-varid">wrap</span> <span class="hs-varop">$</span> <span class="hs-varid">unwrap</span> <span class="hs-varid">x</span> <span class="hs-varop">`op`</span> <span class="hs-varid">unwrap</span> <span class="hs-varid">y</span>
<span class="hs-definition">liftTy</span> <span class="hs-varid">wrap</span> <span class="hs-varid">unwrap</span> <span class="hs-varid">f</span> <span class="hs-keyglyph">=</span> <span class="hs-varid">wrap</span> <span class="hs-varop">.</span> <span class="hs-varid">f</span> <span class="hs-varop">.</span> <span class="hs-varid">unwrap</span>

<span class="hs-definition">liftSum</span> <span class="hs-keyglyph">=</span> <span class="hs-varid">liftTy</span> <span class="hs-conid">Sum</span> <span class="hs-varid">getSum</span>
<span class="hs-definition">liftSum2</span> <span class="hs-keyglyph">=</span> <span class="hs-varid">liftTy2</span> <span class="hs-conid">Sum</span> <span class="hs-varid">getSum</span>

<span class="hs-keyword">instance</span> <span class="hs-layout">(</span><span class="hs-conid">Num</span> <span class="hs-varid">a</span><span class="hs-layout">)</span> <span class="hs-keyglyph">=&gt;</span> <span class="hs-conid">Num</span> <span class="hs-layout">(</span><span class="hs-conid">Sum</span> <span class="hs-varid">a</span><span class="hs-layout">)</span> <span class="hs-keyword">where</span>
  <span class="hs-layout">(</span><span class="hs-varop">+</span><span class="hs-layout">)</span> <span class="hs-keyglyph">=</span> <span class="hs-varid">liftSum2</span> <span class="hs-layout">(</span><span class="hs-varop">+</span><span class="hs-layout">)</span>
  <span class="hs-layout">(</span><span class="hs-comment">-</span><span class="hs-layout">)</span> <span class="hs-keyglyph">=</span> <span class="hs-varid">liftSum2</span> <span class="hs-layout">(</span><span class="hs-comment">-</span><span class="hs-layout">)</span>
  <span class="hs-layout">(</span><span class="hs-varop">*</span><span class="hs-layout">)</span> <span class="hs-keyglyph">=</span> <span class="hs-varid">liftSum2</span> <span class="hs-layout">(</span><span class="hs-varop">*</span><span class="hs-layout">)</span>
  <span class="hs-varid">abs</span> <span class="hs-keyglyph">=</span> <span class="hs-varid">liftSum</span> <span class="hs-varid">abs</span>
  <span class="hs-varid">negate</span> <span class="hs-keyglyph">=</span> <span class="hs-varid">liftSum</span> <span class="hs-varid">negate</span>
  <span class="hs-varid">signum</span> <span class="hs-keyglyph">=</span> <span class="hs-varid">liftSum</span> <span class="hs-varid">signum</span>
  <span class="hs-varid">fromInteger</span> <span class="hs-keyglyph">=</span> <span class="hs-conid">Sum</span> <span class="hs-varop">.</span> <span class="hs-varid">fromInteger</span>

<span class="hs-definition">liftProd</span> <span class="hs-keyglyph">=</span> <span class="hs-varid">liftTy</span> <span class="hs-conid">Product</span> <span class="hs-varid">getProduct</span>
<span class="hs-definition">liftProd2</span> <span class="hs-keyglyph">=</span> <span class="hs-varid">liftTy2</span> <span class="hs-conid">Product</span> <span class="hs-varid">getProduct</span>

<span class="hs-keyword">instance</span> <span class="hs-layout">(</span><span class="hs-conid">Num</span> <span class="hs-varid">a</span><span class="hs-layout">)</span> <span class="hs-keyglyph">=&gt;</span> <span class="hs-conid">Num</span> <span class="hs-layout">(</span><span class="hs-conid">Product</span> <span class="hs-varid">a</span><span class="hs-layout">)</span> <span class="hs-keyword">where</span>
  <span class="hs-layout">(</span><span class="hs-varop">+</span><span class="hs-layout">)</span> <span class="hs-keyglyph">=</span> <span class="hs-varid">liftProd2</span> <span class="hs-layout">(</span><span class="hs-varop">+</span><span class="hs-layout">)</span>
  <span class="hs-layout">(</span><span class="hs-comment">-</span><span class="hs-layout">)</span> <span class="hs-keyglyph">=</span> <span class="hs-varid">liftProd2</span> <span class="hs-layout">(</span><span class="hs-comment">-</span><span class="hs-layout">)</span>
  <span class="hs-layout">(</span><span class="hs-varop">*</span><span class="hs-layout">)</span> <span class="hs-keyglyph">=</span> <span class="hs-varid">liftProd2</span> <span class="hs-layout">(</span><span class="hs-varop">*</span><span class="hs-layout">)</span>
  <span class="hs-varid">abs</span> <span class="hs-keyglyph">=</span> <span class="hs-varid">liftProd</span> <span class="hs-varid">abs</span>
  <span class="hs-varid">negate</span> <span class="hs-keyglyph">=</span> <span class="hs-varid">liftProd</span> <span class="hs-varid">negate</span>
  <span class="hs-varid">signum</span> <span class="hs-keyglyph">=</span> <span class="hs-varid">liftProd</span> <span class="hs-varid">signum</span>
  <span class="hs-varid">fromInteger</span> <span class="hs-keyglyph">=</span> <span class="hs-conid">Product</span> <span class="hs-varop">.</span> <span class="hs-varid">fromInteger</span></pre><br>Or with a few extensions (as noted by Daniel Wagner):<br>

<br><pre><span class="hs-comment">{-# LANGUAGE StandaloneDeriving, GeneralizedNewtypeDeriving #-}</span>

<span class="hs-keyword">import</span> <span class="hs-conid">Data</span><span class="hs-varop">.</span><span class="hs-conid">Monoid</span>

<span class="hs-keyword">deriving</span> <span class="hs-keyword">instance</span> <span class="hs-conid">Num</span> <span class="hs-varid">a</span> <span class="hs-keyglyph">=&gt;</span> <span class="hs-conid">Num</span> <span class="hs-layout">(</span><span class="hs-conid">Sum</span> <span class="hs-varid">a</span><span class="hs-layout">)</span>
<span class="hs-keyword">deriving</span> <span class="hs-keyword">instance</span> <span class="hs-conid">Num</span> <span class="hs-varid">a</span> <span class="hs-keyglyph">=&gt;</span> <span class="hs-conid">Num</span> <span class="hs-layout">(</span><span class="hs-conid">Product</span> <span class="hs-varid">a</span><span class="hs-layout">)</span></pre>

<br>--<br>Dan Burton<br><br>