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

Kim-Ee Yeoh ky3 at atamo.com
Sun Apr 5 02:51:27 UTC 2015


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 at 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
>
>
>
> On Sat, Apr 4, 2015 at 1:46 AM, Sumit Sahrawat, Maths & Computing, IIT
> (BHU) <sumit.sahrawat.apm13 at iitbhu.ac.in> 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 <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
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/beginners/attachments/20150405/ffd19011/attachment.html>


More information about the Beginners mailing list