<html><head><meta http-equiv="Content-Type" content="text/html charset=windows-1252"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>As the instigator of these most recent changes:</div><div><br></div><div>- Yes, absolutely, ($)'s type is quite ugly. In other areas, I've tried to hide the newfound complexity in the type system behind flags, but I missed this one. I consider the current output to be a bug.</div><div><br></div><div>- It's conceivable to have a flag -fdefault-levity, on by default, which looks for levity polymorphism while printing and instantiates all levity variables to Lifted before printing. That would fix the type of ($). Of course, users could specify -fno-default-levity. Would this make you happy?</div><div><br></div><div>- There's a real drawback to flags like -fdefault-levity (and, relatedly, -fprint-explicit-kinds, -fprint-explicit-foralls, -fprint-explicit-coercions, -fprint-equality-relations; the last two are new in 8.0): they hide things from unsuspecting users. We already get a steady trickle of bug reports stemming from confusion around hidden kinds. Users diligently try to make a minimal test case and then someone has to point out that the user is wrong. It's a waste of time and, I'm sure, is frustrating for users. I'm worried about this problem getting worse.</div><div><br></div><div>- It's interesting that the solution to the two problems Takenobu pulls out below (but others have hinted at in this thread) is by having an alternate Prelude for beginners. I believe that having an alternate beginners' Prelude is becoming essential. I know I'm not the first one to suggest this, but a great many issues that teachers of Haskell have raised with me and posts on this and other lists would be solved by an alternate Prelude for beginners.</div><div><br></div><div>- Separate from a full alternate Prelude, and as Iavor suggested, we could just have two ($) operators: a simple one with no baked-in magic or levity polymorphism, and then a levity-polymorphic, sneakily impredicative one. This would be dead easy.</div><div><br></div><div>- Edward is right in that (->) isn't really levity-polymorphic. Well, it is, but it's ad hoc polymorphism not parametric polymorphism. Perhaps in the future we'll make this more robust by actually using type-classes to control it, as we probably should.</div><div><br></div><div>- The case with (->) is different than that with (). (() :: Constraint) and (() :: *) are wholly unrelated types. () is not constraintyness-polymorphic. It's just that we have two wholly unrelated types that happen to share a spelling. So there are hacks in the compiler to disambiguate. Sometimes these hacks do the wrong thing. If we had type-directed name resolution (which I'm not proposing to have!), this would get resolved nicely.</div><div><br></div><div>- The reason that the foralls get printed in ($)'s type is that kind variables appear in the type variables' kinds. GHC thinks that printing the foralls are useful in this case and does so without a flag. This is not directly related to the levity piece. If you say `:t Proxy`, you'll get similar behavior.</div><div><br></div><div><br></div><div>Bottom line: We *need* an alternate Prelude. But that won't happen for 8.0. So in the meantime, I propose -fdefault-levity, awaiting your approval.</div><div><br></div><div>Richard</div><br><div><div>On Feb 5, 2016, at 8:16 AM, Takenobu Tani <<a href="mailto:takenobu.hs@gmail.com">takenobu.hs@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div dir="ltr"><div>Hi,</div><div><br></div><div>I'll worry about the learning curve of beginners.</div><div>Maybe, beginners will try following session in their 1st week.</div><div><br></div><div> ghci> :t foldr</div><div> ghci> :t ($)</div><div><br></div><div>They'll get following result.</div><div><br></div><div><br></div><div>Before ghc7.8:</div><div><br></div><div> Prelude> :t foldr</div><div> foldr :: (a -> b -> b) -> b -> [a] -> b</div><div><br></div><div> Prelude> :t ($)</div><div> ($) :: (a -> b) -> a -> b</div><div><br></div><div> Beginners should only understand about following:</div><div><br></div><div> * type variable (polymorphism)</div><div><br></div><div><br></div><div>After ghc8.0:</div><div><br></div><div> Prelude> :t foldr</div><div> foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b</div><div><br></div><div> Prelude> :t ($)</div><div> ($)</div><div> :: forall (w :: GHC.Types.Levity) a (b :: TYPE w).</div><div> (a -> b) -> a -> b</div><div><br></div><div> Beginners should understand about following things, more:</div><div><br></div><div> * higher order polymorphism (t m)</div><div> * type class (class t =>)</div><div> * universal quantification (forall)</div><div> * kind (type::kind)</div><div> * levity (lifted/unlifted)</div><div><br></div><div>I think it's harder in their 1st week.</div><div>I tried to draw informal illustrations about Foldable,</div><div>but beginners may need ghci-beginner’s mode or something?</div><div><br></div><div>Sorry I don't still have good idea.</div><div><br></div><div>Of course I like Haskell's abstraction :)</div><div><br></div><div>Regards,</div><div>Takenobu</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">2016-02-05 18:19 GMT+09:00 Joachim Breitner <span dir="ltr"><<a href="mailto:mail@joachim-breitner.de" target="_blank">mail@joachim-breitner.de</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
<span class=""><br>
Am Freitag, den 05.02.2016, 09:22 +0200 schrieb Roman Cheplyaka:<br>
> On 02/05/2016 01:31 AM, Edward Z. Yang wrote:<br>
> > I'm not really sure how you would change the type of 'id' based on<br>
> > a language pragma.<br>
> ><br>
> > How do people feel about a cosmetic fix, where we introduce a new<br>
> > pragma, {-# LANGUAGE ShowLevity #-} which controls the display of<br>
> > levity<br>
> > arguments/TYPE. It's off by default but gets turned on by some<br>
> > extensions like MagicHash (i.e. we only show levity if you have<br>
> > enabled extensions where the distinction matters).<br>
><br>
> Yes, I am surprised this isn't the way it's been done. The levity<br>
> arguments should totally be hidden unless requested explicitly.<br>
><br>
> I'd only expect this to be a ghc flag (-fshow-levity), not a language<br>
> pragma, since it should only affect the way types are /shown/.<br>
<br>
</span>shouldn’t this already happen, based on -fprint-explicit-kinds? At<br>
least I would have expected this.<br>
<br>
So we probably either want to make sure that -fno-print-explicit-kinds<br>
also prevents forall’ed kind variables, or add a new flag of that (heh)<br>
kind.<br>
<br>
Greetings,<br>
Joachim<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
Joachim “nomeata” Breitner<br>
<a href="mailto:mail@joachim-breitner.de">mail@joachim-breitner.de</a> • <a href="http://www.joachim-breitner.de/" rel="noreferrer" target="_blank">http://www.joachim-breitner.de/</a><br>
Jabber: <a href="mailto:nomeata@joachim-breitner.de">nomeata@joachim-breitner.de</a> • GPG-Key: 0xF0FBF51F<br>
Debian Developer: <a href="mailto:nomeata@debian.org">nomeata@debian.org</a><br>
<br>
</font></span><br>_______________________________________________<br>
ghc-devs mailing list<br>
<a href="mailto:ghc-devs@haskell.org">ghc-devs@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs</a><br>
<br></blockquote></div><br></div>
_______________________________________________<br>ghc-devs mailing list<br><a href="mailto:ghc-devs@haskell.org">ghc-devs@haskell.org</a><br>http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs<br></blockquote></div><br></body></html>