<div dir="auto">I'm a real beginner, but IIUC might the misunderstanding here be that OP was assuming that since all <i>functions</i> in Haskell take only one argument - and multiple-argument functions just hide this by currying - the same must apply to <i>types</i>; whereas in fact types <i>may</i> take multiple arguments?</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, 19 Dec 2020, 13:02 David James, <<a href="mailto:dj112358@outlook.com">dj112358@outlook.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div lang="EN-GB" link="blue" vlink="#954F72" style="word-wrap:break-word">
<div class="m_-5082830722477533298WordSection1">
<p class="MsoNormal">Hello - some additional comments:</p>
<p class="MsoNormal"><u></u> <u></u></p>
<ol style="margin-top:0cm" start="1" type="1">
<li class="m_-5082830722477533298MsoListParagraph" style="margin-left:0cm">You should probably read
<a href="http://learnyouahaskell.com/higher-order-functions" target="_blank" rel="noreferrer">this</a>, if you haven’t already.</li></ol>
<p class="MsoNormal"><u></u> <u></u></p>
<ol style="margin-top:0cm" start="2" type="1">
<li class="m_-5082830722477533298MsoListParagraph" style="margin-left:0cm">You can think of the declaration</li></ol>
<p class="MsoNormal" style="margin-left:36.0pt;text-indent:36.0pt"><span style="font-family:"Courier New"">fmap :: (a -> b) -> [a] -> [b]<u></u><u></u></span></p>
<p class="MsoNormal" style="text-indent:36.0pt">as meaning: fmap takes two arguments:<u></u><u></u></p>
<p class="MsoNormal" style="margin-left:72.0pt">1<sup>st</sup> arg of type <span style="font-family:"Courier New"">
(a -> b) </span>(i.e. a function, which takes one argument (of type <span style="font-family:"Courier New"">
a</span>) and returns a result (of type <span style="font-family:"Courier New"">b</span>)).<u></u><u></u></p>
<p class="MsoNormal" style="margin-left:36.0pt;text-indent:36.0pt">2<sup>nd</sup> arg of type
<span style="font-family:"Courier New"">[a]</span><u></u><u></u></p>
<p class="MsoNormal" style="text-indent:36.0pt">and returns:<u></u><u></u></p>
<p class="MsoNormal" style="margin-left:36.0pt;text-indent:36.0pt">a result of type
<span style="font-family:"Courier New"">[b]</span><u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal" style="margin-left:36.0pt">An example of a function that can be passed as the first argument would be<u></u><u></u></p>
<p class="MsoNormal" style="margin-left:36.0pt;text-indent:36.0pt"><span style="font-family:"Courier New"">Data.Char.ord :: Char -> Int<u></u><u></u></span></p>
<p class="MsoNormal" style="margin-left:36.0pt">If we pass this to map, we bind the type
<span style="font-family:"Courier New"">a</span> to <span style="font-family:"Courier New"">
Char</span> and the type <span style="font-family:"Courier New"">b</span> to <span style="font-family:"Courier New"">
Int</span>. Then the second argument must be of type <span style="font-family:"Courier New"">
[Char]</span>, and the result will be of type <span style="font-family:"Courier New"">
[Int]</span>. E.g.<u></u><u></u></p>
<p class="MsoNormal" style="margin-left:36.0pt;text-indent:36.0pt"><span style="font-family:"Courier New"">map Data.Char.ord ['F', 'r', 'e', 'd']<u></u><u></u></span></p>
<p class="MsoNormal" style="text-indent:36.0pt">gives<u></u><u></u></p>
<p class="MsoNormal" style="margin-left:36.0pt;text-indent:36.0pt"><span style="font-family:"Courier New"">[70,114,101,100]</span><u></u><u></u></p>
<p class="MsoNormal" style="margin-left:18.0pt"><u></u> <u></u></p>
<ol style="margin-top:0cm" start="3" type="1">
<li class="m_-5082830722477533298MsoListParagraph" style="margin-left:0cm">Haskell allows “currying”. Which means all functions can be “partially applied”. For example, we can apply
<span style="font-family:"Courier New"">map</span> to only one argument. E.g.</li></ol>
<p class="m_-5082830722477533298MsoListParagraph" style="text-indent:36.0pt"><span style="font-family:"Courier New"">map Data.Char.ord</span></p>
<p class="MsoNormal" style="margin-left:36.0pt">is partially applied, and has type</p>
<p class="MsoNormal" style="margin-left:36.0pt"> <span style="font-family:"Courier New"">
[Char] -> [Int]<u></u><u></u></span></p>
<p class="MsoNormal"> You can see this by typing</p>
<p class="m_-5082830722477533298MsoListParagraph" style="text-indent:36.0pt"><span style="font-family:"Courier New"">:t map Data.Char.ord</span><u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal"> (If you just type in<u></u><u></u></p>
<p class="MsoNormal" style="margin-left:36.0pt;text-indent:36.0pt"><span style="font-family:"Courier New"">map Data.Char.ord<u></u><u></u></span></p>
<p class="MsoNormal" style="text-indent:36.0pt">you will get an error, same as if you just typed in<u></u><u></u></p>
<p class="MsoNormal" style="text-indent:36.0pt"> Data.Char.ord<u></u><u></u></p>
<p class="MsoNormal" style="text-indent:36.0pt">Haskell, reasonably, doesn’t know how to print a function)<u></u><u></u></p>
<p class="MsoNormal" style="text-indent:36.0pt"><u></u> <u></u></p>
<p class="MsoNormal" style="text-indent:36.0pt">In fact, all function applications are curried, so even when you do<u></u><u></u></p>
<p class="MsoNormal" style="margin-left:36.0pt;text-indent:36.0pt"><span style="font-family:"Courier New"">map Data.Char.ord ['F', 'r', 'e', 'd']<u></u><u></u></span></p>
<p class="MsoNormal" style="margin-left:36.0pt">It actually applies the 1<sup>st</sup> arg to get a function of type
<span style="font-family:"Courier New"">[Char] -> [Int]</span>, to which it then applies the second arg to get the final value, which it prints. You could write it as this:<u></u><u></u></p>
<p class="MsoNormal" style="margin-left:36.0pt;text-indent:36.0pt"><span style="font-family:"Courier New"">(map Data.Char.ord) ['F', 'r', 'e', 'd']</span><u></u><u></u></p>
<p class="MsoNormal" style="text-indent:36.0pt"><u></u> <u></u></p>
<p class="MsoNormal" style="margin-left:36.0pt">i.e. function application is left-associative. If you don’t put in the brackets to explicitly state differently, you effectively get brackets to the left. This is the same as e.g.<u></u><u></u></p>
<p class="MsoNormal"> <span style="font-family:"Courier New"">
7 – 4 – 1<u></u><u></u></span></p>
<p class="MsoNormal"> meaning<u></u><u></u></p>
<p class="MsoNormal"> <span style="font-family:"Courier New"">
(7 – 4) – 1<u></u><u></u></span></p>
<p class="MsoNormal"> which equals 2. It does not mean<u></u><u></u></p>
<p class="MsoNormal"> <span style="font-family:"Courier New"">
7 – (4 – 1)<u></u><u></u></span></p>
<p class="MsoNormal"> which equals 4. If you want the latter, you need to explicitly write the brackets.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal"> You could of course write<u></u><u></u></p>
<p class="MsoNormal" style="margin-left:36.0pt;text-indent:36.0pt"><span style="font-family:"Courier New"">map (Data.Char.ord ['F', 'r', 'e', 'd'])</span><u></u><u></u></p>
<p class="MsoNormal" style="margin-left:36.0pt">This is syntactically valid, but would attempt to apply
<span style="font-family:"Courier New"">Data.Char.ord</span> to the list of characters, which would give a type error. (And a second type error for attempting to apply
<span style="font-family:"Courier New"">map</span> to the result of <span style="font-family:"Courier New"">
Data.Char.ord</span>.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<ol style="margin-top:0cm" start="4" type="1">
<li class="m_-5082830722477533298MsoListParagraph" style="margin-left:0cm">In type declarations function application is right-associative, so</li></ol>
<p class="MsoNormal" style="margin-left:36.0pt;text-indent:36.0pt"><span style="font-family:"Courier New"">a -> b -> [a] -> [b]<u></u><u></u></span></p>
<p class="MsoNormal" style="margin-left:36.0pt">means<u></u><u></u></p>
<p class="MsoNormal" style="margin-left:36.0pt"> <span style="font-family:"Courier New"">
a -> (b -> ([a] -> [b]))</span><u></u><u></u></p>
<p class="MsoNormal" style="margin-left:36.0pt">which represents a function of one argument (of type
<span style="font-family:"Courier New"">a</span>), which returns a result of type
<span style="font-family:"Courier New"">(b -> ([a] -> [b]))</span>. I’m not sure it would be possible to write such a function, but it would certainly not be the same as
<span style="font-family:"Courier New"">map</span>.</p>
<p class="MsoNormal" style="margin-left:36.0pt"><u></u> <u></u></p>
<p class="MsoNormal" style="margin-left:36.0pt">If you want the brackets in a different place (and we do), then we need to put them explicitly, i.e.</p>
<p class="MsoNormal" style="margin-left:36.0pt;text-indent:36.0pt"><span style="font-family:"Courier New"">(a -> b) -> ([a] -> [b])<u></u><u></u></span></p>
<p class="MsoNormal"> Or, we could you the right-associative default to omit the second pair:</p>
<p class="MsoNormal" style="margin-left:72.0pt"><span style="font-family:"Courier New"">(a -> b) -> [a] -> [b]<u></u><u></u></span></p>
<p class="MsoNormal"><u></u> <u></u></p>
<ol style="margin-top:0cm" start="5" type="1">
<li class="m_-5082830722477533298MsoListParagraph" style="margin-left:0cm">Note that the associativity is simply a matter of syntax. The Haskell definition could have said you always need to put the brackets. Then 7 – 4 – 1 would be a syntax error, you’d
need to put either (7 – 4) – 1 or 7 – (4 – 1). However, many people find typing without brackets helpful most of the time. (Though I must admit that I often “over-bracket” my code, either because I’m not sure of the associativity of different operators, or
because I want to make the code more explicitly clear).<u></u><u></u></li></ol>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal" style="margin-left:36.0pt">Haskell has defined function application to be left-associative because of currying, as described above. Even though<u></u><u></u></p>
<p class="MsoNormal" style="margin-left:36.0pt;text-indent:36.0pt"><span style="font-family:"Courier New"">map Data.Char.ord ['F', 'r', 'e', 'd']<u></u><u></u></span></p>
<p class="MsoNormal" style="margin-left:36.0pt">looks like applying two arguments, it really does
<span style="font-family:"Courier New"">(</span><span style="font-family:"Courier New"">map Data.Char.ord)</span> first.<u></u><u></u></p>
<p class="MsoNormal" style="margin-left:36.0pt"><u></u> <u></u></p>
<p class="MsoNormal" style="margin-left:36.0pt">Similarly, Haskell has defined functions in type declarations to be right-associative for the same reason. The function consumes the first arg first, so in<u></u><u></u></p>
<p class="MsoNormal" style="margin-left:36.0pt"> <span style="font-family:"Courier New"">
(a -> b) -> [a] -> [b]<u></u><u></u></span></p>
<p class="MsoNormal" style="margin-left:36.0pt">after consuming the <span style="font-family:"Courier New"">
(a -> b)</span>, you’re left with a function of type <span style="font-family:"Courier New"">
([a] -> [b])</span>.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Sorry, that ended up quite a bit longer than I expected, but I hope it helps and apologies if I’ve made any errors/etc.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">David.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<div style="border:none;border-top:solid #e1e1e1 1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="MsoNormal" style="border:none;padding:0cm"><b>From: </b><a href="mailto:borgauf@gmail.com" target="_blank" rel="noreferrer">Lawrence Bottorff</a><br>
<b>Sent: </b>19 December 2020 03:37<br>
<b>To: </b><a href="mailto:brubar.cs@gmail.com" target="_blank" rel="noreferrer">Bruno Barbier</a><br>
<b>Cc: </b><a href="mailto:beginners@haskell.org" target="_blank" rel="noreferrer">The Haskell-Beginners Mailing List - Discussion of primarily beginner-level topics related to Haskell</a><br>
<b>Subject: </b>Re: [Haskell-beginners] map type explanation</p>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<p class="MsoNormal">So in effect<u></u><u></u></p>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New"">a -> b -> [a] -> [b]</span><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">wants to be, would be<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New"">a -> (b -> ([a] -> [b]))</span><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">without the parens <span style="font-family:"Courier New"">(</span>which is a natural result of lambda calculus, perhaps?) -- which is not what is meant by
<span style="font-family:"Courier New"">map. </span>But underlying a Haskell type declaration is currying, is it not? At the type declaration level, it's all currying, correct?<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Conceptually, I understand how the <span style="font-family:"Courier New"">
a -> b</span> "event" needs to be a "package" to apply to the list <span style="font-family:"Courier New"">
[a]</span>. The <span style="font-family:"Courier New"">map</span> function commandeers the target function (which alone by itself does some
<span style="font-family:"Courier New"">a -> b</span> evaluation) to be a new object that is then applied to each member of list [a]. Good. So (a -> b) then is a notation that signifies this "package-ness".<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Does anyone have examples of other "packaging" where a function doing some
<span style="font-family:"Courier New"">a -> b</span> is changed to <span style="font-family:"Courier New"">
(a -> b)</span> ?<u></u><u></u></p>
</div>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<div>
<p class="MsoNormal">On Fri, Dec 18, 2020 at 5:18 PM Bruno Barbier <<a href="mailto:brubar.cs@gmail.com" target="_blank" rel="noreferrer">brubar.cs@gmail.com</a>> wrote:<u></u><u></u></p>
</div>
</div>
<p class="MsoNormal" style="margin-left:4.8pt"><br>
Hi Lawrence,<br>
<br>
Lawrence Bottorff <<a href="mailto:borgauf@gmail.com" target="_blank" rel="noreferrer">borgauf@gmail.com</a>> writes:<br>
<br>
> Why is it not just<br>
><br>
> a -> b -> [a] -> [b]<br>
><br>
> again, why the parentheses?<br>
<br>
In Haskell, (->) is a binary operator and is right associative. If you write:<br>
<br>
a -> b -> [a] -> [b]<br>
<br>
it implicitly means:<br>
<br>
a -> (b -> ([a] -> [b]))<br>
<br>
So here, you need explicit parenthesis:<br>
<br>
(a -> b) -> [a] -> [b]<br>
<br>
to mean:<br>
(a -> b) -> ([a] -> [b])<br>
<br>
It's more about parsing binary operators than about types.<br>
<br>
Does it help ?<br>
<br>
Bruno<br>
<br>
> On Fri, Dec 18, 2020 at 4:10 PM Ut Primum <<a href="mailto:utprimum@gmail.com" target="_blank" rel="noreferrer">utprimum@gmail.com</a>> wrote:<br>
><br>
>> Hi,<br>
>><br>
>> a -> b is the type of a function taking arguments of a generic type (we<br>
>> call it a) and returning results of another type, that we call b.<br>
>><br>
>> So<br>
>> (a -> b ) -> [a] -> [b]<br>
>> Means that you have a first argument that is a function (a-> b), a second<br>
>> argument that is a list of elements of the same type of the function input,<br>
>> and that the returned element is a list of things of the type of the output<br>
>> of the function.<br>
>><br>
>> Cheers,<br>
>> Ut<br>
>><br>
>> Il ven 18 dic 2020, 23:02 Lawrence Bottorff <<a href="mailto:borgauf@gmail.com" target="_blank" rel="noreferrer">borgauf@gmail.com</a>> ha<br>
>> scritto:<br>
>><br>
>>> Thank you, but why in<br>
>>><br>
>>> map :: (a -> b) -> [a] -> [b]<br>
>>><br>
>>> are there parentheses around a -> b ? In general, what is the currying<br>
>>> aspect of this?<br>
>>><br>
>>><br>
>>> On Fri, Dec 18, 2020 at 12:43 PM David McBride <<a href="mailto:toad3k@gmail.com" target="_blank" rel="noreferrer">toad3k@gmail.com</a>> wrote:<br>
>>><br>
>>>> They are not parameters, they are the types of the parameters.<br>
>>>><br>
>>>> In this case a can really be anything, Int, Char, whatever, so long as<br>
>>>> the function takes a single argument of that type and the list that is<br>
>>>> given has elements of that same type.<br>
>>>> It is the same for b, it doesn't matter what b ends up being, so long as<br>
>>>> when you call that function the function's return value is compatible with<br>
>>>> the element type of the list that you intended to return from the entire<br>
>>>> statement.<br>
>>>><br>
>>>> You can mess with it yourself in ghci to see how type inference works.<br>
>>>><br>
>>>> >:t show<br>
>>>> :show :: Show a => a -> String<br>
>>>> >:t map show<br>
>>>> map show :: Show a => [a] -> [String]<br>
>>>> > :t flip map [1::Int]<br>
>>>> > flip map [1::Int] :: (Int -> b) -> [b]<br>
>>>><br>
>>>><br>
>>>> On Fri, Dec 18, 2020 at 1:31 PM Lawrence Bottorff <<a href="mailto:borgauf@gmail.com" target="_blank" rel="noreferrer">borgauf@gmail.com</a>><br>
>>>> wrote:<br>
>>>><br>
>>>>> I'm looking at this<br>
>>>>><br>
>>>>> ghci> :type map<br>
>>>>> map :: (a -> b) -> [a] -> [b]<br>
>>>>><br>
>>>>> and wondering what the (a -> b) part is about. map takes a function<br>
>>>>> and applies it to an incoming list. Good. Understood. I'm guessing that the<br>
>>>>> whole Haskell type declaration idea is based on currying, and I do<br>
>>>>> understand how the (a -> b) part "takes" an incoming list, [a] and<br>
>>>>> produces the [b] output. Also, I don't understand a and b very well<br>
>>>>> either. Typically, a is just a generic variable, then b is another<br>
>>>>> generic variable not necessarily the same as a. But how are they being<br>
>>>>> used in this type declaration?<br>
>>>>><br>
>>>>> LB<br>
>>>>> _______________________________________________<br>
>>>>> Beginners mailing list<br>
>>>>> <a href="mailto:Beginners@haskell.org" target="_blank" rel="noreferrer">Beginners@haskell.org</a><br>
>>>>> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" target="_blank" rel="noreferrer">
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><br>
>>>>><br>
>>>> _______________________________________________<br>
>>>> Beginners mailing list<br>
>>>> <a href="mailto:Beginners@haskell.org" target="_blank" rel="noreferrer">Beginners@haskell.org</a><br>
>>>> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" target="_blank" rel="noreferrer">
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><br>
>>>><br>
>>> _______________________________________________<br>
>>> Beginners mailing list<br>
>>> <a href="mailto:Beginners@haskell.org" target="_blank" rel="noreferrer">Beginners@haskell.org</a><br>
>>> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" target="_blank" rel="noreferrer">
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><br>
>>><br>
>> _______________________________________________<br>
>> Beginners mailing list<br>
>> <a href="mailto:Beginners@haskell.org" target="_blank" rel="noreferrer">Beginners@haskell.org</a><br>
>> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" target="_blank" rel="noreferrer">
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><br>
>><br>
> _______________________________________________<br>
> Beginners mailing list<br>
> <a href="mailto:Beginners@haskell.org" target="_blank" rel="noreferrer">Beginners@haskell.org</a><br>
> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" target="_blank" rel="noreferrer">
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
</div>
_______________________________________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org" target="_blank" rel="noreferrer">Beginners@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" rel="noreferrer noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><br>
</blockquote></div>