在我的计算机科学课上过去一两周,我们被问到如何通过“原则转换”来简化和缩短功能。我们还没有收到有关这些作业的反馈,所以我不知道我是否做得对。
这是我最近的练习,以及我尝试解决方案:
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 . (==)
我的尝试:
char c = satisfy (c==)
=> char c = satisfy . c==
=> char c = satisfy . flip ==c
=> char = satisfy . flip ==
=> char = satisfy . (==)
我可以得到一些反馈吗?为赋值提供的代码是不完整的,因此我无法编译它并测试以查看每个转换是否有效。我尝试编写一组类似的函数来自己测试转换,但不幸的是我对Haskell非常苛刻,并且我也无法解决这个问题。
答案 0 :(得分:8)
这是一个循序渐进的方法:
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
我甚至可能会放弃明确扩展该部分,只需从(c==)
转到((==) c)
。
1:http://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-300003.5
2:http://www.haskell.org/haskellwiki/Eta_conversion
答案 1 :(得分:3)
这里有一些错误,首先我要记下相关的类型
char :: Char -> Parser Char
satisfy :: (Char -> Bool) -> Parser Char
(==) :: Char -> Char -> Char
我故意限制一些签名以使其更加愉快。
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
我的方法是
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 . (==)