如何根据特定元素值过滤Haskell中的列表?

时间:2018-03-19 20:12:07

标签: list haskell filter

我有一个电影类型列表,其中电影(导演标题年喜欢不喜欢),对应于电影 - >字符串 - >字符串 - > Int - > [String] - > [串]。 我还有一个函数,它接收喜欢和不喜欢的列表并返回百分比评级,如下所示:

rating :: Likes -> Dislikes -> Int
rating likes dislikes = (((length [likes]) / ((length [dislikes]) + (length [likes]))) * 100)

我的问题: 我无法弄清楚如何使用filter对此列表进行排序,以确定每部电影的评级是否为75%或以上。

这是我目前的尝试:

filterFilm :: Film -> Bool
filterFilm (Film t d y likes dislikes)
            | (rating likes dislikes) > 74  = True
            | otherwise                     = False

-- List film rating with and over 75%
listRating :: Database -> Database
listRating (x:xs) = filter (filterFilm x) (x:xs)

我收到此错误:

Cw 2018.hs:87:29: error:
    • Couldn't match expected type ‘Film -> Bool’
                  with actual type ‘Bool’
    • Possible cause: ‘filterFilm’ is applied to too many arguments
      In the first argument of ‘filter’, namely ‘(filterFilm x)’
      In the expression: filter (filterFilm x) (x : xs)
      In an equation for ‘listRating’:
          listRating (x : xs) = filter (filterFilm x) (x : xs)
   |
87 | listRating (x:xs) = filter (filterFilm x) (x:xs)    |        

有什么建议吗?提前致谢!

1 个答案:

答案 0 :(得分:2)

我认为你以错误的方式使用filterfilter是一个带有两个参数的函数,第一个是谓词a -> Bool,第二个是a列表。

现在,传递给listRating的参数就是该列表,因此listRating l,然后您使用filter调用filter filterFilm l,所以:

listRating :: Database -> Database
listRating l = filter filterFilm l

我们还可以删除函数头部和主体中的l参数,例如:

listRating :: Database -> Database
listRating = filter filterFilm

请注意,您可以将filterFilm功能简化为:

filterFilm :: Film -> Bool
filterFilm (Film t d y likes dislikes) = rating likes dislikes > 74