用于检查字符串中字符的一元谓词
Unary predicate to check for a character being in string
我正在阅读 Real World Haskell, and I tried to implement the splitLines
code myself, and I came up with more or less the same implementation (Chapter 4,第 73 页):
splitLines :: String -> [String]
splitLines [] = []
splitLines ('\r':a) = splitLines a
splitLines ('\n':a) = splitLines a
splitLines a = let (l,r) = break isCRorNL a
in l:splitLines r
where isCRorNL e = ???
--the book defines isCRorNL c = c == '\n' || c == '\r'
但是,我花了太多时间试图以我能想到的最实用和可读的方式编写 isCRorNL
,这样我就可以摆脱 where
并把 splitLines
的最后一个定义变成最英文的句子(就像 compare `on` length
之类的),但没有成功。
我经历过的一些稀疏的想法:
- lambda,
(\c -> c == '\n' || c == '\r')
,对于这样一个简单而具体的任务来说,实在是太强大了,但表现力太差了;
- 此外,它包含大量重复代码and/or它冗长无用。
- 我必须放入
isCRorNL
的任何内容都必须具有类型 Char -> Bool
,
- 因此,如果我为它提供前
n
个参数,它可以具有任何类型 a1 -> a2 -> ... -> an -> Char -> Bool
。
any
函数可以帮助我检查 given 字符是 '\n'
还是 '\r'
或者换句话说,如果它在 Char
s "\n\r"
. 的列表中
- 因为我想检查相等性,我可以将
(==)
传递给我的函数。
- 因此
isCRorNL
可以有类型 (Char -> Char -> Bool) -> [Char] -> Char -> Bool
(或者前两个参数倒置),我可以将 (==)
作为第一个参数传递给它, "\n\r"
作为第二个参数。
- 所以我在寻找一些我可以编写的标准函数来获得这样的函数。
最后放弃了,这样定义:isCRorNL e = any (== e) "\n\r"
;我认为这在可扩展性方面非常好,因为我可以在 "…"
中添加尽可能多的字符,并且我可以更改运算符 ==
;遗憾的是,我不能将函数直接放在使用它的地方,因为我无法将它写成部分应用的函数。
你会怎么做?
当我在问题中查找link并访问它时(第一次),我发现代码块被读者评论,并且第一个评论在[=11=下] 阅读:
augustss 2008-04-23
[...] If you're making a point about functional
style maybe you should use
isLineSeparator = (`elem` "\r\n")
所以我一直在考虑函数的组合,而最简单的解决方案是部分应用一个如此简单的函数,elem
。此处的缺点是用于检查相等性的运算符内置于 elem
中并且无法更改。尽管如此,我还是觉得自己没有想到 elem
是愚蠢的。
我正在阅读 Real World Haskell, and I tried to implement the splitLines
code myself, and I came up with more or less the same implementation (Chapter 4,第 73 页):
splitLines :: String -> [String]
splitLines [] = []
splitLines ('\r':a) = splitLines a
splitLines ('\n':a) = splitLines a
splitLines a = let (l,r) = break isCRorNL a
in l:splitLines r
where isCRorNL e = ???
--the book defines isCRorNL c = c == '\n' || c == '\r'
但是,我花了太多时间试图以我能想到的最实用和可读的方式编写 isCRorNL
,这样我就可以摆脱 where
并把 splitLines
的最后一个定义变成最英文的句子(就像 compare `on` length
之类的),但没有成功。
我经历过的一些稀疏的想法:
- lambda,
(\c -> c == '\n' || c == '\r')
,对于这样一个简单而具体的任务来说,实在是太强大了,但表现力太差了; - 此外,它包含大量重复代码and/or它冗长无用。
- 我必须放入
isCRorNL
的任何内容都必须具有类型Char -> Bool
, - 因此,如果我为它提供前
n
个参数,它可以具有任何类型a1 -> a2 -> ... -> an -> Char -> Bool
。 any
函数可以帮助我检查 given 字符是'\n'
还是'\r'
或者换句话说,如果它在Char
s"\n\r"
. 的列表中
- 因为我想检查相等性,我可以将
(==)
传递给我的函数。 - 因此
isCRorNL
可以有类型(Char -> Char -> Bool) -> [Char] -> Char -> Bool
(或者前两个参数倒置),我可以将(==)
作为第一个参数传递给它,"\n\r"
作为第二个参数。 - 所以我在寻找一些我可以编写的标准函数来获得这样的函数。
最后放弃了,这样定义:isCRorNL e = any (== e) "\n\r"
;我认为这在可扩展性方面非常好,因为我可以在 "…"
中添加尽可能多的字符,并且我可以更改运算符 ==
;遗憾的是,我不能将函数直接放在使用它的地方,因为我无法将它写成部分应用的函数。
你会怎么做?
当我在问题中查找link并访问它时(第一次),我发现代码块被读者评论,并且第一个评论在[=11=下] 阅读:
augustss 2008-04-23
[...] If you're making a point about functional style maybe you should use
isLineSeparator = (`elem` "\r\n")
所以我一直在考虑函数的组合,而最简单的解决方案是部分应用一个如此简单的函数,elem
。此处的缺点是用于检查相等性的运算符内置于 elem
中并且无法更改。尽管如此,我还是觉得自己没有想到 elem
是愚蠢的。