
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

readFile.head xs = readFile . (head xs) For that to work, (head xs) must evaluate to a function with which readFile can compose. But that wouldn't be the type you're wanting. readFile $ head xs = readFile (head xs) Graham On 03/04/2015 10:23 PM, Vale Cofer-Shabica 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

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

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
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
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
-- Regards Sumit Sahrawat

Thank you for all the responses! Sumit's point about function
application binding most strongly was the point I was missing. I was
lured by the possibility of writing my function in point-free style as
Mike indicated: readFirst = readFile.head, but ghc complained about
differing numbers of arguments when I included the different case for
the empty list.
Thanks again,
vale
On Sat, Apr 4, 2015 at 1:46 AM, Sumit Sahrawat, Maths & Computing, IIT
(BHU)
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
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
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
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
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
-- Regards
Sumit Sahrawat

Hi Vale, Here's something to consider: readFirst [] = System.IO.getContents readFirst (x:_) = readFile x This is considered good style because the pattern-matching is obviously complete. 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. -- Kim-Ee On Sun, Apr 5, 2015 at 2:31 AM, Vale Cofer-Shabica < vale.cofershabica@gmail.com> wrote:
Thank you for all the responses! Sumit's point about function application binding most strongly was the point I was missing. I was lured by the possibility of writing my function in point-free style as Mike indicated: readFirst = readFile.head, but ghc complained about differing numbers of arguments when I included the different case for the empty list.
Thanks again, vale
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
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 .
On Sat, Apr 4, 2015 at 1:46 AM, Sumit Sahrawat, Maths & Computing, IIT (BHU)
wrote: 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
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
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
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
-- Regards
Sumit Sahrawat
Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

Thank you Kim-Ee,
This is the version I ended up using!
-vale
On Sat, Apr 4, 2015 at 10:51 PM, Kim-Ee Yeoh
Hi Vale,
Here's something to consider:
readFirst [] = System.IO.getContents readFirst (x:_) = readFile x
This is considered good style because the pattern-matching is obviously complete.
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.
-- Kim-Ee
On Sun, Apr 5, 2015 at 2:31 AM, Vale Cofer-Shabica
wrote: Thank you for all the responses! Sumit's point about function application binding most strongly was the point I was missing. I was lured by the possibility of writing my function in point-free style as Mike indicated: readFirst = readFile.head, but ghc complained about differing numbers of arguments when I included the different case for the empty list.
Thanks again, vale
On Sat, Apr 4, 2015 at 1:46 AM, Sumit Sahrawat, Maths & Computing, IIT (BHU)
wrote: 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
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
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
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
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
-- Regards
Sumit Sahrawat
Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
participants (5)
-
Graham Gill
-
Kim-Ee Yeoh
-
Mike Meyer
-
Sumit Sahrawat, Maths & Computing, IIT (BHU)
-
Vale Cofer-Shabica