基于亚历山大·普罗科菲耶夫的回答:
repetitions x = concat (map tail (filter (\x -> (length x) > 1) (List.group (word (filter (\c -> (c >= 'a' && c <= 'z') || (c>='A' && c <= 'Z') || c==' ') x)))))
删除不必要的括号:
repetitions x = concat (map tail (filter (\x -> length x > 1) (List.group (word (filter (\c -> c >= 'a' && c <= 'z' || c>='A' && c <= 'Z' || c==' ') x)))))
使用 $ 删除更多括号(如果结束括号位于表达式的末尾,则每个 $ 可以替换一个左括号):
repetitions x = concat $ map tail $ filter (\x -> length x > 1) $ List.group $ word $ filter (\c -> c >= 'a' && c <= 'z' || c>='A' && c <= 'Z' || c==' ') x
用 Data.Char 中的函数替换字符范围,合并 concat 和 map:
repetitions x = concatMap tail $ filter (\x -> length x > 1) $ List.group $ word $ filter (\c -> isAlpha c || isSeparator c) x
使用无点样式的部分和柯里化来简化(\x -> length x > 1) to ((>1) . length)
. 这与从右到左管道中的length
(>1) (部分应用的运算符或section )结合。
repetitions x = concatMap tail $ filter ((>1) . length) $ List.group $ word $ filter (\c -> isAlpha c || isSeparator c) x
消除显式 "x" 变量以使整体表达式无点:
repetitions = concatMap tail . filter ((>1) . length) . List.group . word . filter (\c -> isAlpha c || isSeparator c)
现在整个函数,从右到左读取,是一个管道,它只过滤字母或分隔符,将其拆分为单词,将其分成组,过滤具有超过 1 个元素的组,然后将剩余的组减少到第一个每个元素。