我写了这段代码,现在需要将其重写为pointfree风格:
num_of_occ ele list = length(filter(==ele)list)
于是我做了这个:
num_of_occ ele = length . filter((==)ele)
它有效。然后我做了这个:
num_of_occ = length . filter . (==)
而且它并没有告诉我我思路中哪里出了问题?
我写了这段代码,现在需要将其重写为pointfree风格:
num_of_occ ele list = length(filter(==ele)list)
于是我做了这个:
num_of_occ ele = length . filter((==)ele)
它有效。然后我做了这个:
num_of_occ = length . filter . (==)
而且它并没有告诉我我思路中哪里出了问题?
这是一个常见的错误。以下是解决方法:
num_of_occ = (length .) . filter . (==)
这与您的函数接受参数的数量有关。函数组合 (.)
操作符适用于只接受一个参数的函数,您需要将其应用两次 (f .) .
才能使其适用于接受两个参数的函数。
实际上,在 Hackage 上有一个程序可以自动将代码片段转换为无点编程样式,如果您想尝试一下。
$ cabal install pointfree $ pointfree 'num_of_occ ele list = length (filter (== ele) list)' num_of_occ = (length .) . filter . (==)
如已指出,这需要类型签名才能正常工作。出于提高 Haskell 性能的目的,这个限制相对单调但比较不明显。您可以打开 NoMonomorphismRestriction
扩展,或添加一个类型签名:
num_of_occ :: Eq a => a -> [a] -> Int
num_of_occ = (length .) . filter . (==)
a.hs:1:31: 由于使用了“==”,没有实例可以匹配 (Eq a0)
。 - ciemborEq a ->
。应该是 Eq a =>
。 - Will Ness