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

Vale Cofer-Shabica vale.cofershabica at gmail.com
Mon Apr 6 15:31:54 UTC 2015


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 <ky3 at atamo.com> wrote:
> 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
>
>
>
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>


More information about the Beginners mailing list