<div dir="ltr">By way of a counterpoint to the "showing complicated things alienates beginners" argument, remember that to a beginner there are already very many things on the screen that they won't (and needn't immediately) understand. For instance, this is what a simple `<font face="monospace, monospace">stack ghci</font>` in my home directory says to me:<div><br></div><div><div><div><font face="monospace, monospace">$ stack ghci</font></div><div><font face="monospace, monospace">Run from outside a project, using implicit global project config</font></div><div><font face="monospace, monospace">Using resolver: lts-2.22 from implicit global project's config file: /home/linuxadmin/.stack/global/stack.yaml</font></div><div><font face="monospace, monospace">Error parsing targets: The specified targets matched no packages.</font></div><div><font face="monospace, monospace">Perhaps you need to run 'stack init'?</font></div><div><font face="monospace, monospace">Warning: build failed, but optimistically launching GHCi anyway</font></div><div><font face="monospace, monospace">Configuring GHCi with the following packages:</font></div><div><font face="monospace, monospace">GHCi, version 7.8.4: <a href="http://www.haskell.org/ghc/">http://www.haskell.org/ghc/</a>  :? for help</font></div><div><font face="monospace, monospace">Loading package ghc-prim ... linking ... done.</font></div><div><font face="monospace, monospace">Loading package integer-gmp ... linking ... done.</font></div><div><font face="monospace, monospace">Loading package base ... linking ... done.</font></div><div><font face="monospace, monospace">Ok, modules loaded: none.</font></div><div><font face="monospace, monospace">Prelude></font></div></div></div><div><br></div><div>There's a lot of stuff there you don't need as a beginner. The line beginning 'Error' is a bit scary, as is the 'Warning'. The advice to run 'stack init' is not good advice. The advice to use :? for help is probably the most beginner-useful thing in all that and it looks like line noise rather than a thing you might want to actually type!</div><div><br></div><div>My point is that beginners have to start out ignoring things they don't understand anyway - part of the process of learning a new language is coming to terms with what's important and what's not in any given context. I'm not saying I'm a big fan of the addition to the type sig of ($), and would definitely appreciate a flag to switch it off, but I don't think this'll make it significantly harder to teach my next victims.</div><div><br></div><div>Cheers,</div><div><br></div><div>David</div></div><div class="gmail_extra"><br><div class="gmail_quote">On 6 February 2016 at 18:14, Manuel Gómez <span dir="ltr"><<a href="mailto:targen@gmail.com" target="_blank">targen@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On Sat, Feb 6, 2016 at 12:42 PM, Edward Kmett <<a href="mailto:ekmett@gmail.com">ekmett@gmail.com</a>> wrote:<br>
> The primitives that GHC uses to implement arrays, references and the like<br>
> live in #. We then wrap them in something in * before exposing them to the<br>
> user, but you can shave a level of indirection by knowing what lives in #<br>
> and what doesn't.<br>
<br>
</span>Yes!  Let’s not forget, of course, that these (or similar) have been<br>
in GHC for many, many years, right in the Prelude:<br>
<br>
```<br>
> :i Int Char Float Double IO Integer<br>
data Int = GHC.Types.I# <a href="http://GHC.Prim.Int#" rel="noreferrer" target="_blank">GHC.Prim.Int#</a><br>
data Char = GHC.Types.C# GHC.Prim.Char#<br>
data Float = GHC.Types.F# GHC.Prim.Float#<br>
data Double = GHC.Types.D# GHC.Prim.Double#<br>
newtype IO a<br>
  = <a href="http://GHC.Types.IO" rel="noreferrer" target="_blank">GHC.Types.IO</a> (GHC.Prim.State# GHC.Prim.RealWorld<br>
                  -> (# GHC.Prim.State# GHC.Prim.RealWorld, a #))<br>
data Integer<br>
  = integer-gmp-1.0.0.0:GHC.Integer.Type.S# !<a href="http://GHC.Prim.Int#" rel="noreferrer" target="_blank">GHC.Prim.Int#</a><br>
  | integer-gmp-1.0.0.0:<a href="http://GHC.Integer.Type.Jp#" rel="noreferrer" target="_blank">GHC.Integer.Type.Jp#</a> {-# UNPACK<br>
#-}integer-gmp-1.0.0.0:GHC.Integer.Type.BigNat<br>
  | integer-gmp-1.0.0.0:GHC.Integer.Type.Jn# {-# UNPACK<br>
#-}integer-gmp-1.0.0.0:GHC.Integer.Type.BigNat<br>
```<br>
<br>
Stepping outside the Prelude, yet well within beginner territory,<br>
brings even more fun:<br>
<br>
```<br>
> :i Map Set<br>
data Map k a<br>
  = containers-0.5.6.2:Data.Map.Base.Bin {-# UNPACK<br>
#-}containers-0.5.6.2:Data.Map.Base.Size<br>
                                         !k<br>
                                         a<br>
                                         !(Map k a)<br>
                                         !(Map k a)<br>
  | containers-0.5.6.2:Data.Map.Base.Tip<br>
data Set a<br>
  = containers-0.5.6.2:Data.Set.Base.Bin {-# UNPACK<br>
#-}containers-0.5.6.2:Data.Set.Base.Size<br>
                                         !a<br>
                                         !(Set a)<br>
                                         !(Set a)<br>
  | containers-0.5.6.2:Data.Set.Base.Tip<br>
```<br>
<br>
Unboxed types, the UNPACK pragma, references to GHC.Prim (which easily<br>
lead to confusing exploration), unboxed tuples, an unboxed State<br>
monad, RealWorld, bang patterns, unexported constructors,<br>
implementation details for abstract types… all of them available right<br>
from the prompt of the Prelude using the main tool for exploratory<br>
learning that beginners rely on.<br>
<br>
I’m not saying this is a good thing and I’m not saying this should be<br>
fixed.  I’m not even saying this is comparable to the situation with $<br>
and I’m likewise not saying presenting these concepts to beginners<br>
should be thought of as comparable to presenting levity polymorphism<br>
to beginners.  It is nonetheless relevant context to this discussion;<br>
the Prelude has always had concepts unfriendly to beginners readily<br>
available, and Haskell beginner teachers have always had to work<br>
around these issues.  Students have always asked about these things.<br>
<span class=""><br>
> But even if you never care about #, Int, Double, etc. are of kind *,<br>
> Functors are of kind * -> *, etc. so to talk about the type of types at all<br>
> you need to be able to talk about these concepts at all with any rigor, and<br>
> to understand why Maybe Maybe isn't a thing.<br>
<br>
</span>In my personal teaching experience, it is extremely helpful to discuss<br>
kinds in the first introduction of type constructors, after covering<br>
types with no parameters.  This is especially helpful in discussing<br>
how the hierarchy leading to Monad works, and why things like<br>
«instance Functor (Tree Int) where …» don’t make sense and why<br>
«instance Functor Tree where …» must be parametric in the type of the<br>
thing in the tree, which in turn motivates a lot more discussion.<br>
<br>
Teaching kinds is teaching Haskell basics.  It is not an advanced<br>
topic.  It ought to be covered near the very first lessons on Haskell<br>
for absolute beginners.<br>
<div class="HOEnZb"><div class="h5">_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><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>
</div></div></blockquote></div><br></div>