<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>