Reputation: 263
This past week or two in my computer science class, we've been asked show how functions can be simplified and shortened through "principled transformations." We have not been receiving feedback on these assignments so I have no idea if I'm doing it right.
Here's my latest exercise, and my attempt at a solution:
Show by a series of principled transformations that we can define:
char :: Char -> Parser Char
char c = satisfy (c==)
as
char :: Char -> Parser Char
char = satisfy . (==)
My attempt:
char c = satisfy (c==)
=> char c = satisfy . c==
=> char c = satisfy . flip ==c
=> char = satisfy . flip ==
=> char = satisfy . (==)
Could I get some feedback please? The code provided for the assignment is incomplete, so I cannot compile it and test to see if each transformation works. I tried writing a similar set of functions to test the transformations myself, but I unfortunately am very bad at and new to Haskell so I couldn't figure that out either.
Upvotes: 2
Views: 259
Reputation: 53881
Well there are a few errors here, first I'm going to write down relevant types
char :: Char -> Parser Char
satisfy :: (Char -> Bool) -> Parser Char
(==) :: Char -> Char -> Char
I've deliberately restricted some signatures to make this more pleasant.
char c = satisfy (c==)
char c = satisfy . c== -- This is a parse error, not sure what you meant
char c = satisfy . flip ==c -- Also wrong, flip swaps arguments,
-- but this function has only one argument
char = satisfy . flip == -- Eta conversion is right, this code is
-- still a parse error - you should check code with ghci or winhugs
My approach would be
char c = satisfy (c==)
char c = satisfy $ (\c -> \d -> c == d) c -- Explicitly undo sections
char c = satisfy . (\c d -> c == d) $ c -- f(g x) === (f . g) x by the
-- definition of composition
char c = (satisfy . (==)) c
char = satisfy . (==)
Upvotes: 3
Reputation: 6695
Here's a step-by-step approach:
char c = satisfy (c==)
char c = satisfy (\x -> c == x) -- Sections [1]
char c = satisfy (\x -> (==) c x) -- Prefix form
char c = satisfy ((==) c) -- Eta reduction [2]
char c = (.) satisfy (==) c -- Composition: `(.) f g x = f (g x)`
char c = (satisfy . (==)) c -- Infix form
char = satisfy . (==) -- Eta reduction
I would maybe even forgo explicitly expanding the section and simply go from (c==)
to ((==) c)
.
1: http://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-300003.5
2: http://www.haskell.org/haskellwiki/Eta_conversion
Upvotes: 8