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@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@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@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@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners