我在删除此函数中的参数'e'时遇到问题:
numocc e = map length . (map . filter . (==)) e
该函数检查二维列表中的元素的出现次数(列表中的列表)。所以你称之为:
numocc 1 [[1,2],[2,3,2,1,1],[3]]
结果:[1,2,0]
参数 e 位于等号两侧的最右侧,并未包含在任何参数中。因此,我应该能够删除它以获得无点功能:
numocc = map length . (map . filter . (==))
但是我收到了这个错误:
在应用程序中输入错误 表达式:地图长度。地图。过滤器。 (==) 术语:地图长度 类型:[[b]] - > [INT] 不符合:([[a]] - > [[a]]) - > [INT]
这是什么问题?感谢。
答案 0 :(得分:6)
您的原始功能正在被解析为
numocc e = (map length) . ((map . filter . (==)) e)
因此,您不能只删除e
,因为它在技术上并未出现在定义的末尾。但是,如果您定义运算符
(.:) :: (c -> d) -> (a -> b -> c) -> (a -> b -> d)
(.:) = (.) . (.)
然后你可以把它写成
numocc = map length .: (map . filter . (==))
map . filter . (==)
上的括号是必需的,因为由于固定规则,您无法混合.
和.:
。
然而,在这一点上,你只是让这个功能更难阅读和维护。最好将其分解为更小的部分并引入一些中间名称,同时添加正确的类型签名并为函数提供更好的名称:
numOccurrences :: Eq a => a -> [a] -> Int
numOccurrences valueToCount values = length (filter (== valueToCount) values)
numOccurrencesInSublists :: Eq a => a -> [[a]] -> [Int]
numOccurrencesInSublists valueToCount = map (numOccurrences valueToCount)
这更具可读性,不依赖于花哨的操作员,更清楚地表达您的意图。由于在单个列表中计数的情况是一个单独的函数,您现在也可以在其他地方使用它。
请记住,优雅的代码并不是要让它尽可能地短,而是要尽可能地让它变得清晰。描述性名称(不一定是长名称),显式参数和小型可组合单位是最好的。