<div dir="ltr">It is a type level operator. You can parameterize things by it:<div><br></div><div><font face="monospace, monospace">type Foo f = f Int String<br><br></font></div><div><font face="monospace, monospace">foo :: Foo (->)<br>foo = show</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">-- Write instances for it:</font></div><div><font face="monospace, monospace">class Profunctor p where</font></div><div><font face="monospace, monospace">  dimap :: (a -> b) -> (c -> d) -> p b c -> p a d</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">instance Profunctor (->) where</font></div><div><font face="monospace, monospace">  dimap ab cd bc = cd . bc . ab</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">-- Define aliases for it:</font></div><div><font face="monospace, monospace">type Func a b = a -> b</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">map :: Func a b -> [a] -> [b]</font></div><div><font face="monospace, monospace">-- or even,</font></div><div><font face="monospace, monospace">map :: Func a b -> Func [a] [b]</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">-- Use it prefix</font></div><div><font face="monospace, monospace">dropWhile :: ((->) a Bool) -> [a] -> [a]</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">-- Partially apply it:</font></div><div><font face="monospace, monospace">instance MonadReader r ((->) r) where<br>  ask = id</font></div></div><div class="gmail_extra"><br clear="all"><div><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div>Matt Parsons</div></div></div></div>
<br><div class="gmail_quote">On Wed, Aug 15, 2018 at 10:53 PM, Paul <span dir="ltr"><<a href="mailto:aquagnu@gmail.com" target="_blank">aquagnu@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hmm, very interesting question, really: what is the "->" in functions signatures: type-level operator or syntax only?<div class="HOEnZb"><div class="h5"><br>
<br>
<br>
16.08.2018 01:20, Massimo Zaniboni wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Il 15/08/2018 23:06, Stefan Chacko ha scritto:<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
 3. Why do we use clinches in such definitions. I concluded  you need<br>
    clinches if a function is not associative<br>
such as (a-b)+c  . (Int->Int)->Int->Int<br>
<br>
But also if a higher order function needs more than one argument. (a->b)->c .<br>
<br>
Can you please explain it ?<br>
</blockquote>
<br>
  funXYZ :: Int -> Int -> Int -> Int<br>
  funXYZ x y z = (x - y) + z<br>
<br>
if you rewrite in pure lamdda-calculus, without any syntax-sugars it became<br>
<br>
  fun_XYZ :: (Int -> (Int -> (Int -> Int)))<br>
  fun_XYZ = \x -> \y -> \z -> (x - y) + z<br>
<br>
so fun_XYZ is a function `\x -> ...` that accepts x, and return a function, that accepts a parameter y, and return a function, etc...<br>
<br>
You can also rewrite as:<br>
<br>
  funX_YZ :: Int -> (Int -> (Int -> Int))<br>
  funX_YZ x = \y -> \z -> (x - y) + z<br>
<br>
or<br>
<br>
  funXY_Z :: Int -> Int -> (Int -> Int)<br>
  funXY_Z x y = \z -> (x - y) + z<br>
<br>
and finally again in the original<br>
<br>
  funXYZ_ :: Int -> Int -> Int -> Int<br>
  funXYZ_ x y z = (x - y) + z<br>
<br>
I used different names only for clarity, but they are the same exact function in Haskell.<br>
<br>
In lambda-calculus the form<br>
<br>
  \x y z -> (x - y) + z<br>
<br>
is syntax sugar for<br>
<br>
  \x -> \y -> \z -> (x - y) + z<br>
<br>
On the contrary (as Francesco said)<br>
<br>
  (Int -> Int) -> Int -> Int<br>
<br>
is a completely different type respect<br>
<br>
  Int -> Int -> Int -> Int<br>
<br>
In particular a function like<br>
<br>
  gHX :: (Int -> Int) -> Int -> Int<br>
  gHX h x = h x<br>
<br>
has 2 parameters, and not 3. The first parameter has type (Int -> Int), the second type Int, and then it returns an Int. Equivalent forms are:<br>
<br>
  g_HX :: (Int -> (Int -> Int))<br>
  g_HX = \h -> \x -> h x<br>
<br>
  gH_X :: (Int -> Int) -> (Int -> Int)<br>
  gH_X h = \x -> h x<br>
<br>
  gHX :: (Int -> Int) -> Int -> Int<br>
  gHX_ h x = h x<br>
<br>
<br>
IMHO it is similar to logic: intuitively it seems easy and natural, but if you reflect too much, it is not easy anymore... but after you internalize some rules, it is easy and natural again.<br>
<br>
Regards,<br>
Massimo<br>
______________________________<wbr>_________________<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-bi<wbr>n/mailman/listinfo/haskell-caf<wbr>e</a><br>
Only members subscribed via the mailman list are allowed to post.<br>
</blockquote>
<br>
______________________________<wbr>_________________<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-bi<wbr>n/mailman/listinfo/haskell-caf<wbr>e</a><br>
Only members subscribed via the mailman list are allowed to post.</div></div></blockquote></div><br></div>