<div dir="ltr"><div>Hello Sylvain, and thanks again :)</div><div><br></div><div>When adding the forall I can compile the code without a problem.</div><div><br></div><div>For the types b1 b2 b3, they are of course not what I want (b must be unique in the context of the question).</div><div>But the type for the function with b1, b2 and b3 is what I got when I did not give a type signature to the compiler/interpreter (which is understandable since it has no reason to assume they would be one and the same).</div><div><br></div><div>I will try the Functional dependency (though I haven't learned about this yet).</div><div><br></div><div>But the main question remains:</div><div><span class="gmail-im"><br>"add x y = wrap $ unwrap x + unwrap y" can be compiled/interpreted, and when I ask about its type, the answer is:</span></div><div><span class="gmail-im">":t add"<br></span></div><div><div><span class="gmail-im"><span class="gmail-im">"add :: (Num a, Newtype a b1, Newtype a b2, Newtype a b3) => b2 -> b3 -> b1"</span></span></div><div><span class="gmail-im"><span class="gmail-im"><br></span></span></div><div><span class="gmail-im"><span class="gmail-im">Then when I add that same type signature, like so:<br></span></span></div><span class="gmail-im"></span></div><div><span class="gmail-im"><span class="gmail-im">"add :: (Num a, Newtype a b1, Newtype a b2, Newtype a b3) => b2 -> b3 -> b1</span></span></div><div><span class="gmail-im"><span class="gmail-im"><span class="gmail-im"> add x y = wrap $ unwrap x + unwrap y"</span></span></span></div><div><span class="gmail-im"><span class="gmail-im"><span class="gmail-im">the compiler refuses it for ambiguity reasons.</span></span></span></div><div><span class="gmail-im"><span class="gmail-im"><span class="gmail-im"><br></span></span></span></div><div><span class="gmail-im"><span class="gmail-im"><span class="gmail-im">So the question is: How come the compiler does not accept its own type signature? Why had it not refused to compile even without one, and only</span></span></span></div><div><span class="gmail-im"><span class="gmail-im"><span class="gmail-im">upon specification of said signature did the compilation break?</span></span></span></div><div><span class="gmail-im"><span class="gmail-im"><span class="gmail-im"><br></span></span></span></div><div><span class="gmail-im"><span class="gmail-im"><span class="gmail-im">Regards,<br></span></span></span></div><div><span class="gmail-im"><span class="gmail-im"><span class="gmail-im">Michel :)<br></span></span></span></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Apr 10, 2019 at 4:29 PM Sylvain Henry <<a href="mailto:sylvain@haskus.fr">sylvain@haskus.fr</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
  
    
  
  <div bgcolor="#FFFFFF">
    <p><br>
    </p>
    <div class="gmail-m_8298268524492928696moz-cite-prefix">On 10/04/2019 15:29, Michel Haber
      wrote:<br>
    </div>
    <blockquote type="cite">
      
      <div dir="ltr">
        <div dir="ltr">
          <div dir="ltr">
            <div dir="ltr">
              <div dir="ltr">
                <div>Hello,</div>
                <div>Thanks for the answer.</div>
                <div>I tried the code you sent, but now I'm getting a
                  "type variable not in score" error. (I added both
                  extensions)<br>
                </div>
                <div>This is the whole code pertaining to this problem
                  (with the extensions mentioned before):</div>
                <div><br>
                  class Newtype a b where<br>
                    wrap   :: a -> b<br>
                    unwrap :: b -> a</div>
                <div><br>
                </div>
                <div>newtype MyInt   = MyInt   Int<br>
                  newtype YourInt = YourInt Int<br>
                  <br>
                  instance Newtype Int MyInt where<br>
                    wrap = MyInt<br>
                    unwrap (MyInt i) = i<br>
                  <br>
                  instance Newtype Int YourInt where<br>
                    wrap = YourInt<br>
                    unwrap (YourInt i) = i</div>
                <div><br>
                  add :: (Num a, Newtype a b1, Newtype a b2, Newtype a
                  b3) => b2 -> b3 -> b1<br>
                  add x y = wrap @a @b1 $ unwrap @a x + unwrap @a y<br>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote>
    <p>You need to add the "forall a b1 b2 b3" to be allowed to use "@a"
      (with ScopedTypeVariables extension).<br>
    </p>
    <blockquote type="cite">
      <div dir="ltr">
        <div dir="ltr">
          <div dir="ltr">
            <div dir="ltr">
              <div dir="ltr">
                <div><br>
                </div>
                <div>For further reference, the exercice to which this
                  code should be a solution can be found at:</div>
                <div><a href="https://github.com/i-am-tom/haskell-exercises/blob/answers/09-MultiParamTypeClasses/src/Exercises.hs" target="_blank">https://github.com/i-am-tom/haskell-exercises/blob/answers/09-MultiParamTypeClasses/src/Exercises.hs</a></div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote>
    <p>> <span class="gmail-m_8298268524492928696pl-c">c. Write a function that adds together
        two values of the same type, </span><span class="gmail-m_8298268524492928696pl-c"><span class="gmail-m_8298268524492928696pl-c">providing that the type is a newtype around some
          type with a 'Num' instance.</span></span></p>
    <p><span class="gmail-m_8298268524492928696pl-c"><span class="gmail-m_8298268524492928696pl-c">You only need a single "b"
          type instead of b1, b2 b3. Also I think you could use a
          Function Dependency in the "Newtype" definition (because when
          we know "b" we know "a"). It will make the code of "add' much
          simpler.</span></span></p>
    <blockquote type="cite">
      <div dir="ltr">
        <div dir="ltr">
          <div dir="ltr">
            <div dir="ltr">
              <div dir="ltr">
                <div><br>
                </div>
                <div>Finally, the question remains: Is it "normal" that
                  ghci behave differently depending on whether</div>
                <div>the type signature is declared or not? (Remember
                  that the signature is given by ghci itself)</div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote>
    <p>Finally it is not related to GHCi (we get the same
      errors/warnings when we compile) but to the AllowAmbiguousTypes
      extension:
<a class="gmail-m_8298268524492928696moz-txt-link-freetext" href="https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html?#extension-AllowAmbiguousTypes" target="_blank">https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html?#extension-AllowAmbiguousTypes</a></p>
    <p>The type of "add" is ambiguous according to the definition in the
      manual.</p>
    <p><br>
    </p>
    <p>My advice would be to use a Functional dependency in your
      definition of NewType and then you can forget about ambiguous
      types, type applications, scoped type variables, etc. for now. The
      reported type of "add" by ghci becomes non-ambiguous and
      everything is well :) (and I guess that it was the point of the
      exercise)</p>
    <p>Regards,<br>
      Sylvain<br>
    </p>
    <p><br>
    </p>
    <blockquote type="cite">
      <div dir="ltr">
        <div dir="ltr">
          <div dir="ltr">
            <div dir="ltr">
              <div dir="ltr">
                <div><br>
                </div>
                <div>Thanks again,</div>
                <div>Michel :)<br>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <br>
      <div class="gmail_quote">
        <div dir="ltr" class="gmail_attr">On Wed, Apr 10, 2019 at 1:28
          PM Sylvain Henry <<a href="mailto:sylvain@haskus.fr" target="_blank">sylvain@haskus.fr</a>> wrote:<br>
        </div>
        <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
          <div bgcolor="#FFFFFF">
            <p>Hi,</p>
            <p>It looks like an effect of ExtendedDefaultRules:
              <a class="gmail-m_8298268524492928696gmail-m_5239024630282165491moz-txt-link-freetext" href="https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ghci.html#extension-ExtendedDefaultRules" target="_blank">https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ghci.html#extension-ExtendedDefaultRules</a></p>
            <p>It's hard to tell without the code but maybe something
              like that will do:</p>
            <p><tt>{-# LANGUAGE ScopedTypeVariables #-}</tt><tt><br>
              </tt><tt>{-# LANGUAGE TypeApplications #-}</tt><tt><br>
              </tt><tt><br>
              </tt><tt>add :: forall a b1 b2 b3. (Num a, Newtype a b1,
                Newtype a b2, Newtype a b3) => b2 -> b3 -> b1</tt><tt><br>
              </tt><tt>add x y = wrap @a @b1 $ unwrap @a x + unwrap @a y</tt><tt><br>
              </tt><br>
            </p>
            <p>-Sylvain<br>
            </p>
            <div class="gmail-m_8298268524492928696gmail-m_5239024630282165491moz-cite-prefix">On
              10/04/2019 12:32, Michel Haber wrote:<br>
            </div>
            <blockquote type="cite">
              <div dir="ltr">
                <div dir="ltr">
                  <div dir="ltr">
                    <div dir="ltr">
                      <div>Hello Cafe,</div>
                      <div><br>
                      </div>
                      <div>I was trying to load a module containing this
                        function in ghci:<br>
                        "add x y = wrap $ unwrap x + unwrap y"<br>
                      </div>
                      <div>with the following extensions activated:</div>
                      <div><br>
                      </div>
                      <div>ConstraintKinds<br>
                        DataKinds<br>
                        DeriveFunctor<br>
                        DuplicateRecordFields<br>
                        FlexibleContexts<br>
                        FlexibleInstances<br>
                        GADTs<br>
                        KindSignatures<br>
                        MultiParamTypeClasses<br>
                        PolyKinds<br>
                        TypeFamilies<br>
                        TypeOperators<br>
                        AllowAmbiguousTypes<br>
                      </div>
                      <div><br>
                      </div>
                      <div>And it loaded without problem.</div>
                      <div><br>
                      </div>
                      <div>So then I tested its type with ":t add",
                        which gave:</div>
                      <div>add :: (Num a, Newtype a b1, Newtype a b2,
                        Newtype a b3) => b2 -> b3 -> b1</div>
                      <div><br>
                      </div>
                      <div>Then I added this signature to the function
                        in the module. This caused ghci</div>
                      <div>to refuse to load it and give the following
                        error:</div>
                      <div><br>
                      </div>
                      <div>src/Exercises.hs:55:11: error:<br>
                            • Could not deduce (Newtype Integer b1)<br>
                                arising from a use of ‘wrap’<br>
                              from the context: (Num a, Newtype a b1,
                        Newtype a b2, Newtype a b3)<br>
                                bound by the type signature for:<br>
                                           add :: forall a b1 b2 b3.<br>
                                                  (Num a, Newtype a b1,
                        Newtype a b2, Newtype a b3) =><br>
                                                  b2 -> b3 -> b1<br>
                                at src/Exercises.hs:54:1-74<br>
                            • In the expression: wrap $ unwrap x +
                        unwrap y<br>
                              In an equation for ‘add’: add x y = wrap $
                        unwrap x + unwrap y<br>
                           |<br>
                        55 | add x y = wrap $ unwrap x + unwrap y<br>
                           |           ^^^^^^^^^^^^^^^^^^^^^^^^^^<br>
                        <br>
                        src/Exercises.hs:55:18: error:<br>
                            • Could not deduce (Newtype Integer b2)<br>
                                arising from a use of ‘unwrap’<br>
                              from the context: (Num a, Newtype a b1,
                        Newtype a b2, Newtype a b3)<br>
                                bound by the type signature for:<br>
                                           add :: forall a b1 b2 b3.<br>
                                                  (Num a, Newtype a b1,
                        Newtype a b2, Newtype a b3) =><br>
                                                  b2 -> b3 -> b1<br>
                                at src/Exercises.hs:54:1-74<br>
                            • In the first argument of ‘(+)’, namely
                        ‘unwrap x’<br>
                              In the second argument of ‘($)’, namely
                        ‘unwrap x + unwrap y’<br>
                              In the expression: wrap $ unwrap x +
                        unwrap y<br>
                           |<br>
                        55 | add x y = wrap $ unwrap x + unwrap y<br>
                           |                  ^^^^^^^^<br>
                        <br>
                        src/Exercises.hs:55:29: error:<br>
                            • Could not deduce (Newtype Integer b3)<br>
                                arising from a use of ‘unwrap’<br>
                              from the context: (Num a, Newtype a b1,
                        Newtype a b2, Newtype a b3)<br>
                                bound by the type signature for:<br>
                                           add :: forall a b1 b2 b3.<br>
                                                  (Num a, Newtype a b1,
                        Newtype a b2, Newtype a b3) =><br>
                                                  b2 -> b3 -> b1<br>
                                at src/Exercises.hs:54:1-74<br>
                            • In the second argument of ‘(+)’, namely
                        ‘unwrap y’<br>
                              In the second argument of ‘($)’, namely
                        ‘unwrap x + unwrap y’<br>
                              In the expression: wrap $ unwrap x +
                        unwrap y<br>
                           |<br>
                        55 | add x y = wrap $ unwrap x + unwrap y<br>
                           |                             ^^^^^^^^<br>
                        Failed, no modules loaded.</div>
                      <div><br>
                      </div>
                      <div>This does not make sense to me, since I only
                        used the signature that ghci itself gave me.</div>
                      <div><br>
                      </div>
                      <div>Is this a bug? if not, could someone please
                        explain this behaviour to me?</div>
                      <div><br>
                      </div>
                      Thanks,
                      <div>Michel<br>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
              <br>
              <fieldset class="gmail-m_8298268524492928696gmail-m_5239024630282165491mimeAttachmentHeader"></fieldset>
              <pre class="gmail-m_8298268524492928696gmail-m_5239024630282165491moz-quote-pre">_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
<a class="gmail-m_8298268524492928696gmail-m_5239024630282165491moz-txt-link-freetext" href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a>
Only members subscribed via the mailman list are allowed to post.</pre>
            </blockquote>
          </div>
          _______________________________________________<br>
          Haskell-Cafe mailing list<br>
          To (un)subscribe, modify options or view archives go to:<br>
          <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
          Only members subscribed via the mailman list are allowed to
          post.</blockquote>
      </div>
    </blockquote>
  </div>

</blockquote></div>