<div dir="ltr">
  
    
  
  <div text="#000000" bgcolor="#FFFFFF">
    <div class="m_8602359256493275747moz-cite-prefix">Thank you Alex for that comprehensive
      answer. That's very helpful. I'd considered a newtype, but I really wondered what prevented me from using or was bad about the approach I described.</div><div class="m_8602359256493275747moz-cite-prefix"><br></div><div class="m_8602359256493275747moz-cite-prefix">Regards,</div><div class="m_8602359256493275747moz-cite-prefix">Graham<br>
      <br>
      On 04-Jun-2018 1:10 AM, Alex Rozenshteyn wrote:<br>
    </div>
    <blockquote type="cite">
      <div dir="ltr">
        <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">I
          want to say that if a type is Bounded, then it is also
          UpperBounded and LowerBounded.</blockquote>
        <div><br>
        </div>
        <div dir="ltr">
          <div>Seems reasonable<br>
          </div>
        </div>
        <div dir="ltr">
          <div> </div>
          <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">If a type is both
            UpperBounded and LowerBounded, then it is also Bounded.</blockquote>
          <div><br>
          </div>
        </div>
        <div dir="ltr">
          <div>Danger Will Robinson. Nothing stops modules
            (realistically, in two different library) from defining
            incompatible UpperBounded and LowerBounded instances; for
            example, I may want `lowerBound :: Bool` to be `True`, while
            you may want `upperBound :: Bool` to be `True`; when they
            are both imported, bad things can happen. In this case,
            requiring an Ord constraint and adding documentation on
            lawful instances would pretty much solve the problem, but in
            general, this is an unwise thing to do.</div>
          <div><br>
          </div>
          <div>Specifically, it is usually a bad idea to have a type
            class that should have an instance for a type whenever that
            type has instances of some combination of other classes.</div>
          <div><br>
          </div>
          <div>Three ways around it:</div>
          <div>
            <ul>
              <li>Use a newtype wrapper: define `newtype
                LowerUpperBounded` and have the instance be
                `(LowerBounded a, UpperBounded a) => Bounded
                (LowerUpperBounded a)`</li>
              <li>Defer instance definition to concrete types: if you
                know that a specific type has both super-instances, you
                can explicitly instantiate it at the sub-instance</li>
              <li>Define a constraint alias: (this requires some more
                advanced extensions, so I'm only mentioning it as an
                option for completeness' sake) Using `ConstraintKinds`,
                you can define `type Bounded a = (LowerBounded a,
                UpperBounded a)`; this makes the two definitions
                synonymous.</li>
            </ul>
            <p>To your immediate question, I <i>think</i> what's
              happening is that when you're trying to do `minBound ::
              Bar` it looks for an instance `Bounded Bar` and finds the
              unique one; then it needs to satisfy the constraints, so
              it looks for `LowerBounded Bar` and `UpperBounded Bar`,
              the latter of which has two possible instances, neither of
              which is marked overlapping or incoherent.</p>
            <p>You'll notice that if you use `-fdefer-type-errors` you
              will be able to get the `minBound` of `Bar` (though for
              some reason you need to bind it to a variable), but not
              the `maxBound`.<br>
            </p>
          </div>
        </div>
        <div dir="ltr">
          <div>You should also note that if you use the `OVERLAPPABLE`
            pragma rather than the `INCOHERENT` one, you get the same
            results, and that is generally considered less risky.<br>
          </div>
          <br>
          <div class="gmail_quote">
            <div dir="ltr">On Sun, Jun 3, 2018 at 8:43 PM Graham Gill
              <<a href="mailto:math.simplex@gmail.com" target="_blank">math.simplex@gmail.com</a>>
              wrote:<br>
            </div>
            <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
              <div dir="ltr">
                <div>Please see the paste: <a href="https://pastebin.com/zBim7Zkx" target="_blank">https://pastebin.com/zBim7Zkx</a></div>
                <div><br>
                </div>
                I'm experimenting with defining UpperBounded and
                LowerBounded typeclasses. An example type belonging to
                the latter that is not also Bounded would be type
                Natural from Numeric.Natural.
                <div><br>
                </div>
                <div>I want to say that if a type is Bounded, then it is
                  also UpperBounded and LowerBounded. If a type is both
                  UpperBounded and LowerBounded, then it is also
                  Bounded.</div>
                <div><br>
                </div>
                <div>To express the constraints, I need
                  FlexibleInstances and UndecidableInstances extensions.
                  These allow the module to load into ghci (8.4.2) with
                  only a warning, but, without the INCOHERENT pragmas, I
                  get an overlapping instance error if I try to evaluate
                  minBound, maxBound, upperBound or lowerBound
                  instantiated to either of the types Foo or Bar.</div>
                <div><br>
                </div>
                <div>A solution is to apply the INCOHERENT pragma to the
                  instances at lines 11, 14 and 17. Reading over
                  section 10.8.3.6. Overlapping instances in the GHC
                  User Guide, I believe I understand. (Is there a better
                  solution?)</div>
                <div><br>
                </div>
                <div>In the paste, I have INCOHERENT pragmas only at
                  lines 11 and 17. This gives me the following behaviour
                  in ghci:</div>
                <div>
                  <ol>
                    <li>minBound, maxBound, upperBound and lowerBound
                      instantiated to type Foo all function as expected,
                      evaluating to the appropriate lower or upper
                      bound.<br>
                    </li>
                    <li>upperBound and maxBound instantiated at Bar give
                      overlapping instance errors for UpperBounded, as
                      expected.</li>
                    <li>lowerBound :: Bar evaluates to C, as expected.</li>
                    <li>minBound :: Bar gives an overlapping instance
                      error for UpperBounded:</li>
                  </ol>
                  <div><span style="font-family:monospace"><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">*UpperLowerBounded>
                        minBound :: Bar
                      </span><br>
                      <br>
                      <span style="font-weight:bold;color:rgb(0,0,0);background-color:rgb(255,255,255)"><interactive>:141:1:
                      </span><span style="font-weight:bold;color:rgb(255,84,84);background-color:rgb(255,255,255)">error:</span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">
                      </span><br>
                      <span style="font-weight:bold;color:rgb(0,0,0);background-color:rgb(255,255,255)">
                           • Overlapping instances for UpperBounded Bar</span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">
                      </span><br>
                      <span style="font-weight:bold;color:rgb(0,0,0);background-color:rgb(255,255,255)">
                               arising from a use of ‘minBound’</span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">
                      </span><br>
                      <span style="font-weight:bold;color:rgb(0,0,0);background-color:rgb(255,255,255)">
                             Matching instances:</span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">
                      </span><br>
                      <span style="font-weight:bold;color:rgb(0,0,0);background-color:rgb(255,255,255)">
                               instance [safe] Bounded a =>
                        UpperBounded a</span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">
                      </span><br>
                      <span style="font-weight:bold;color:rgb(0,0,0);background-color:rgb(255,255,255)">
                                 -- Defined at
                        UpperLowerBounded.hs:14:10</span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">
                      </span><br>
                      <span style="font-weight:bold;color:rgb(0,0,0);background-color:rgb(255,255,255)">
                               instance [safe] UpperBounded Bar --
                        Defined at UpperLowerBounded.hs:31:10</span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">
                      </span><br>
                      <span style="font-weight:bold;color:rgb(0,0,0);background-color:rgb(255,255,255)">
                           • In the expression: minBound :: Bar</span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">
                      </span><br>
                      <span style="font-weight:bold;color:rgb(0,0,0);background-color:rgb(255,255,255)">
                             In an equation for ‘it’: it = minBound ::
                        Bar</span><br>
                      <span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">
                      </span><br>
                    </span><br>
                  </div>
                </div>
                <div>It's #4 that I don't understand. An explanation
                  would be very much appreciated. (Also, what's a [safe]
                  instance?)</div>
                <div><br>
                </div>
                <div>Regards,</div>
                <div>Graham</div>
                <div><br>
                </div>
              </div>
              _______________________________________________<br>
              Beginners mailing list<br>
              <a href="mailto:Beginners@haskell.org" target="_blank">Beginners@haskell.org</a><br>
              <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><br>
            </blockquote>
          </div>
        </div>
      </div>
      <br>
      <fieldset class="m_8602359256493275747mimeAttachmentHeader"></fieldset>
      <br>
      <pre>_______________________________________________
Beginners mailing list
<a class="m_8602359256493275747moz-txt-link-abbreviated" href="mailto:Beginners@haskell.org" target="_blank">Beginners@haskell.org</a>
<a class="m_8602359256493275747moz-txt-link-freetext" href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a>
</pre>
    </blockquote>
    <p><br>
    </p>
  </div>

</div>