<div dir="ltr"><div><div><div><div>Hi Vale,<br><br></div>Here's something to consider:<br><br></div>readFirst [] = System.IO.getContents<br></div>readFirst (x:_) = readFile x<br><br></div>This is considered good style because the pattern-matching is obviously complete. <br><br>In the original, the use of "head" might be flagged by various lint-like tools even though it's safe in the context, albeit not immediately so.<br><div><br></div></div><div class="gmail_extra"><br clear="all"><div><div class="gmail_signature">-- Kim-Ee</div></div>
<br><div class="gmail_quote">On Sun, Apr 5, 2015 at 2:31 AM, Vale Cofer-Shabica <span dir="ltr"><<a href="mailto:vale.cofershabica@gmail.com" target="_blank">vale.cofershabica@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Thank you for all the responses! Sumit's point about function<br>
application binding most strongly was the point I was missing. I was<br>
lured by the possibility of writing my function in point-free style as<br>
Mike indicated: readFirst = readFile.head, but ghc complained about<br>
differing numbers of arguments when I included the different case for<br>
the empty list.<br>
<br>
Thanks again,<br>
vale<br>
<div class="HOEnZb"><div class="h5"><br>
<br>
<br>
On Sat, Apr 4, 2015 at 1:46 AM, Sumit Sahrawat, Maths & Computing, IIT<br>
(BHU) <<a href="mailto:sumit.sahrawat.apm13@iitbhu.ac.in">sumit.sahrawat.apm13@iitbhu.ac.in</a>> wrote:<br>
> To reiterate what others have said,<br>
><br>
>    readFile . head xs<br>
> == readFile . (head xs)     { function application binds strongest }<br>
> == (.) readFile (head xs)   { operators are also functions }<br>
><br>
> The types,<br>
><br>
>    (.)      :: (b -> c) -> (a -> b) -> (a -> c)<br>
>    readFile :: FilePath -> IO String<br>
>    head xs  :: FilePath<br>
><br>
> This cannot work as the types don't match. On the other hand, using ($)<br>
> instead of (.) will work.<br>
> Try writing that out and reasoning with the types on pen and paper, as an<br>
> exercise.<br>
><br>
> If you're interested, there is an excellent post about equational reasoning<br>
> here: <a href="http://www.haskellforall.com/2013/12/equational-reasoning.html" target="_blank">http://www.haskellforall.com/2013/12/equational-reasoning.html</a><br>
><br>
> Enjoy :)<br>
><br>
> On 4 April 2015 at 08:10, Mike Meyer <<a href="mailto:mwm@mired.org">mwm@mired.org</a>> wrote:<br>
>><br>
>> As is often the case with Haskell, your answer is in the types:<br>
>><br>
>> Prelude> :t ($)<br>
>> ($) :: (a -> b) -> a -> b<br>
>> Prelude> :t (.)<br>
>> (.) :: (b -> c) -> (a -> b) -> a -> c<br>
>><br>
>> So $ takes a function and applies it to a value. . takes two functions and<br>
>> composes them and applies the result to a value.<br>
>><br>
>> So readFirst xs = (readFile.head) xs, or just readFirst = readFile . head.<br>
>> But readFirst xs = (readFile $ head) xs will also fail, because readFile<br>
>> doesn't work on objects of type head.<br>
>><br>
>> On Fri, Apr 3, 2015 at 9:23 PM, Vale Cofer-Shabica<br>
>> <<a href="mailto:vale.cofershabica@gmail.com">vale.cofershabica@gmail.com</a>> wrote:<br>
>>><br>
>>> Could someone please explain why the commented line fails<br>
>>> spectacularly while the final line succeeds?<br>
>>><br>
>>> >import System.IO (getContents)<br>
>>> >import System.Environment (getArgs)<br>
>>><br>
>>> >fileInput :: IO String<br>
>>> >fileInput = getArgs>>=readFirst where<br>
>>> >  readFirst :: [FilePath] -> IO String<br>
>>> >  readFirst [] = System.IO.getContents<br>
>>> >--readFirst xs = readFile.head xs<br>
>>> >  readFirst xs = readFile $ head xs<br>
>>><br>
>>><br>
>>> I'm particularly confused given the following typings (from ghci):<br>
>>><br>
>>> readFile.head :: [FilePath] -> IO String<br>
>>> readFile.head [] :: a -> IO String<br>
>>><br>
>>> And this is still stranger:<br>
>>><br>
>>> :type readFile.head ["foo", "bar"]<br>
>>><br>
>>> <interactive>:28:16:<br>
>>>     Couldn't match expected type `a0 -> FilePath'<br>
>>>                 with actual type `[Char]'<br>
>>>     In the expression: "foo"<br>
>>>     In the first argument of `head', namely `["foo", "bar"]'<br>
>>>     In the second argument of `(.)', namely `head ["foo", "bar"]'<br>
>>><br>
>>> <interactive>:28:23:<br>
>>>     Couldn't match expected type `a0 -> FilePath'<br>
>>>                 with actual type `[Char]'<br>
>>>     In the expression: "bar"<br>
>>>     In the first argument of `head', namely `["foo", "bar"]'<br>
>>>     In the second argument of `(.)', namely `head ["foo", "bar"]'<br>
>>><br>
>>><br>
>>> Many thanks in advance,<br>
>>> vale<br>
>>> _______________________________________________<br>
>>> Beginners mailing list<br>
>>> <a href="mailto:Beginners@haskell.org">Beginners@haskell.org</a><br>
>>> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><br>
>><br>
>><br>
>><br>
>> On Fri, Apr 3, 2015 at 9:23 PM, Vale Cofer-Shabica<br>
>> <<a href="mailto:vale.cofershabica@gmail.com">vale.cofershabica@gmail.com</a>> wrote:<br>
>>><br>
>>> Could someone please explain why the commented line fails<br>
>>> spectacularly while the final line succeeds?<br>
>>><br>
>>> >import System.IO (getContents)<br>
>>> >import System.Environment (getArgs)<br>
>>><br>
>>> >fileInput :: IO String<br>
>>> >fileInput = getArgs>>=readFirst where<br>
>>> >  readFirst :: [FilePath] -> IO String<br>
>>> >  readFirst [] = System.IO.getContents<br>
>>> >--readFirst xs = readFile.head xs<br>
>>> >  readFirst xs = readFile $ head xs<br>
>>><br>
>>><br>
>>> I'm particularly confused given the following typings (from ghci):<br>
>>><br>
>>> readFile.head :: [FilePath] -> IO String<br>
>>> readFile.head [] :: a -> IO String<br>
>>><br>
>>> And this is still stranger:<br>
>>><br>
>>> :type readFile.head ["foo", "bar"]<br>
>>><br>
>>> <interactive>:28:16:<br>
>>>     Couldn't match expected type `a0 -> FilePath'<br>
>>>                 with actual type `[Char]'<br>
>>>     In the expression: "foo"<br>
>>>     In the first argument of `head', namely `["foo", "bar"]'<br>
>>>     In the second argument of `(.)', namely `head ["foo", "bar"]'<br>
>>><br>
>>> <interactive>:28:23:<br>
>>>     Couldn't match expected type `a0 -> FilePath'<br>
>>>                 with actual type `[Char]'<br>
>>>     In the expression: "bar"<br>
>>>     In the first argument of `head', namely `["foo", "bar"]'<br>
>>>     In the second argument of `(.)', namely `head ["foo", "bar"]'<br>
>>><br>
>>><br>
>>> Many thanks in advance,<br>
>>> vale<br>
>>> _______________________________________________<br>
>>> Beginners mailing list<br>
>>> <a href="mailto:Beginners@haskell.org">Beginners@haskell.org</a><br>
>>> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><br>
>><br>
>><br>
>><br>
>> _______________________________________________<br>
>> Beginners mailing list<br>
>> <a href="mailto:Beginners@haskell.org">Beginners@haskell.org</a><br>
>> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><br>
>><br>
><br>
><br>
><br>
> --<br>
> Regards<br>
><br>
> Sumit Sahrawat<br>
_______________________________________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org">Beginners@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><br>
</div></div></blockquote></div><br></div>