【问题标题】:Unary predicate to check for a character being in string一元谓词检查字符串中的字符
【发布时间】:2019-12-22 19:06:13
【问题描述】:

我正在阅读Real World Haskell,我尝试自己实现splitLines 代码,我想出了或多或少相同的实现(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') 对于这样一个简单而具体的任务来说功能太强大而表达能力太低了;
  • 此外,它包含大量重复代码和/或冗长无用。
  • 无论我在isCRorNL 中输入什么,都必须输入Char -> Bool
  • 因此,如果我为其提供第一个 n 参数,它可以具有任何类型 a1 -> a2 -> ... -> an -> Char -> Bool
  • any 函数可以帮助我检查 given 字符是 '\n' 还是 '\r',或者换句话说,它是否在 Chars @ 的列表中987654338@.
  • 由于我想检查是否相等,我可以将(==) 传递给我的函数。
  • 因此isCRorNL 可以具有(Char -> Char -> Bool) -> [Char] -> Char -> Bool 类型(或将前两个参数反转),我可以将(==) 作为第一个参数传递给它,"\n\r" 作为第二个参数传递给它。
  • 所以我一直在寻找一些我可以编写的标准函数来获得这样的函数。

最后我放弃了,这样定义:isCRorNL e = any (== e) "\n\r";我认为这在可扩展性方面非常好,因为我可以在"…" 中添加尽可能多的字符,并且我可以更改运算符==;可悲的是,我不能将函数直接放在使用它的地方,因为我无法将其编写为部分应用的函数。

你会怎么做?

【问题讨论】:

    标签: haskell functional-programming currying


    【解决方案1】:

    当我在问题中查找链接并访问它(第一次)时,我意识到代码块是由读者评论的,splitLines 下的第一条评论是:

    8 月 2008-04-23

    [...] 如果您要说明功能性 样式也许你应该使用

    isLineSeparator = (`elem` "\r\n")
    

    结果我一直在思考函数的组合,而最简单的解决方案是部分应用一个如此简单的函数,elem。这里的缺点是用于检查相等性的运算符是内置在elem 中的,并且无法更改。尽管如此,我还是觉得自己没有想到elem自己很愚蠢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-10
      • 2012-10-23
      • 1970-01-01
      • 1970-01-01
      • 2019-02-17
      • 1970-01-01
      • 1970-01-01
      • 2011-01-16
      相关资源
      最近更新 更多