[Haskell-beginners] (.) vs ($)

Sumit Sahrawat, Maths & Computing, IIT (BHU) sumit.sahrawat.apm13 at iitbhu.ac.in
Sat Apr 4 05:46:59 UTC 2015


To reiterate what others have said,

   readFile . head xs
== readFile . (head xs)     { function application binds strongest }
== (.) readFile (head xs)   { operators are also functions }

The types,

   (.)      :: (b -> c) -> (a -> b) -> (a -> c)
   readFile :: FilePath -> IO String
   head xs  :: FilePath

This cannot work as the types don't match. On the other hand, using ($)
instead of (.) will work.
Try writing that out and reasoning with the types on pen and paper, as an
exercise.

If you're interested, there is an excellent post about equational reasoning
here: http://www.haskellforall.com/2013/12/equational-reasoning.html

Enjoy :)

On 4 April 2015 at 08:10, Mike Meyer <mwm at mired.org> wrote:

> As is often the case with Haskell, your answer is in the types:
>
> Prelude> :t ($)
> ($) :: (a -> b) -> a -> b
> Prelude> :t (.)
> (.) :: (b -> c) -> (a -> b) -> a -> c
>
> So $ takes a function and applies it to a value. . takes two functions and
> composes them and applies the result to a value.
>
> So readFirst xs = (readFile.head) xs, or just readFirst = readFile .
> head. But readFirst xs = (readFile $ head) xs will also fail, because
> readFile doesn't work on objects of type head.
>
> On Fri, Apr 3, 2015 at 9:23 PM, Vale Cofer-Shabica <
> vale.cofershabica at gmail.com> wrote:
>
>> Could someone please explain why the commented line fails
>> spectacularly while the final line succeeds?
>>
>> >import System.IO (getContents)
>> >import System.Environment (getArgs)
>>
>> >fileInput :: IO String
>> >fileInput = getArgs>>=readFirst where
>> >  readFirst :: [FilePath] -> IO String
>> >  readFirst [] = System.IO.getContents
>> >--readFirst xs = readFile.head xs
>> >  readFirst xs = readFile $ head xs
>>
>>
>> I'm particularly confused given the following typings (from ghci):
>>
>> readFile.head :: [FilePath] -> IO String
>> readFile.head [] :: a -> IO String
>>
>> And this is still stranger:
>>
>> :type readFile.head ["foo", "bar"]
>>
>> <interactive>:28:16:
>>     Couldn't match expected type `a0 -> FilePath'
>>                 with actual type `[Char]'
>>     In the expression: "foo"
>>     In the first argument of `head', namely `["foo", "bar"]'
>>     In the second argument of `(.)', namely `head ["foo", "bar"]'
>>
>> <interactive>:28:23:
>>     Couldn't match expected type `a0 -> FilePath'
>>                 with actual type `[Char]'
>>     In the expression: "bar"
>>     In the first argument of `head', namely `["foo", "bar"]'
>>     In the second argument of `(.)', namely `head ["foo", "bar"]'
>>
>>
>> Many thanks in advance,
>> vale
>> _______________________________________________
>> Beginners mailing list
>> Beginners at haskell.org
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>>
>
>
> On Fri, Apr 3, 2015 at 9:23 PM, Vale Cofer-Shabica <
> vale.cofershabica at gmail.com> wrote:
>
>> Could someone please explain why the commented line fails
>> spectacularly while the final line succeeds?
>>
>> >import System.IO (getContents)
>> >import System.Environment (getArgs)
>>
>> >fileInput :: IO String
>> >fileInput = getArgs>>=readFirst where
>> >  readFirst :: [FilePath] -> IO String
>> >  readFirst [] = System.IO.getContents
>> >--readFirst xs = readFile.head xs
>> >  readFirst xs = readFile $ head xs
>>
>>
>> I'm particularly confused given the following typings (from ghci):
>>
>> readFile.head :: [FilePath] -> IO String
>> readFile.head [] :: a -> IO String
>>
>> And this is still stranger:
>>
>> :type readFile.head ["foo", "bar"]
>>
>> <interactive>:28:16:
>>     Couldn't match expected type `a0 -> FilePath'
>>                 with actual type `[Char]'
>>     In the expression: "foo"
>>     In the first argument of `head', namely `["foo", "bar"]'
>>     In the second argument of `(.)', namely `head ["foo", "bar"]'
>>
>> <interactive>:28:23:
>>     Couldn't match expected type `a0 -> FilePath'
>>                 with actual type `[Char]'
>>     In the expression: "bar"
>>     In the first argument of `head', namely `["foo", "bar"]'
>>     In the second argument of `(.)', namely `head ["foo", "bar"]'
>>
>>
>> Many thanks in advance,
>> vale
>> _______________________________________________
>> Beginners mailing list
>> Beginners at haskell.org
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>>
>
>
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
>


-- 
Regards

Sumit Sahrawat
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/beginners/attachments/20150404/b79ef363/attachment.html>


More information about the Beginners mailing list