Haskell电影搜索

时间:2019-12-22 12:55:41

标签: haskell

我是Haskell的新手,我有一个项目,如果列表中的条件满足,则需要给出True,我已经执行了另一个功能来检查分数是否高于或导演是否相同,但是现在我需要将这些条件合并在一起,但是我被卡住了,不知道该怎么做。

该测试用例的功能需要返回真值:

search (director "Christopher Nolan") movies == [("Inception", 8.8, "Christopher Nolan"), ("The Dark Knight", 9.0, "Christopher Nolan")]

search (imdbAtLeast 8.2) movies == [("Green Book", 8.3, "Peter Farrelly"), ("Inception", 8.8, "Christopher Nolan"), ("The Dark Knight", 9.0, "Christopher Nolan")]

search (and_ (director "Christopher Nolan") (imdbAtLeast 8.9)) movies == [("The Dark Knight", 9.0, "Christopher Nolan")]

search (or_ (imdbAtLeast 7.5) (director "Rian Johnson")) [("The Last Jedi", 7.2, "Rian Johnson"), ("Sicario", 7.6, "Denis Villeneuve")] == [("The Last Jedi", 7.2, "Rian Johnson"), ("Sicario", 7.6, "Denis Villeneuve")]

search (\_ -> True) [] == []

search (\_ -> False) movies == []

我的代码,直到那部分:

type Movie = (String, Double, String)

-- movies :: [(String, Double, String)]
movies :: [Movie]
movies = [ ("Green Book", 8.3, "Peter Farrelly")
         , ("Inception", 8.8, "Christopher Nolan")
         , ("Incredibles 2", 7.7, "Brad Bird")
         , ("The Dark Knight", 9.0, "Christopher Nolan")
         ] 
imdbAtLeast :: Double -> (String,Double,String) -> Bool 
imdbAtLeast pointgive (_, point, _) =  point >= pointgive

director  :: String  -> (String,Double,String) -> Bool 
director  directorgive  (_, _, director) =  director == directorgive

and_ :: (Movie -> Bool) -> (Movie -> Bool) -> Movie -> Bool
and_ p q m = p m && q m

or_ :: (Movie -> Bool) -> (Movie -> Bool) -> Movie -> Bool
or_ p q m = p m || q m

1 个答案:

答案 0 :(得分:1)

好的,看来您走对了。您对搜索功能的类型有所了解,让我们写下来:

search :: (Movie -> Bool) -> [Movie] -> [Movie]

让我们尝试从首要原则中找出答案。

第一个参数是一个函数。我们将其称为谓词p。使用此功能我们无能为力。最明显的是将它应用于电影,但到目前为止我们还没有。

第二个参数是电影列表。让我们进行图案匹配。第一种情况是[]

search p [] = (??)

好吧,我们需要在这里返回电影列表,我认为我们不应该凭空补拍,所以我们应该不返回任何电影。的确,如果您搜索没有电影的列表,那么肯定可以得到的就是一无所有。在这种情况下,我们不使用谓词参数,因此让我们写_来表明您显然不使用它:

search _ [] = []

另一种情况是列表的开头,其余为列表的开头。我们称​​电影为头m,按照惯例,尾称为ms

search p (m:ms) = (??)

这时,我们现在有了一部影片,可以使用我们的函数p来调用它,然后考虑一下结果:

search p (m:ms) =
    if p m
    then (??)
    else (??)

那么我们在这里做什么?如果p m为true,则应在输出中包含m,如果为false,则不应包含。让我们将其余的输出r称为结果

search p (m:ms) = if p m then p:r else r
  where r = (??)

现在我们所要做的就是弄清楚剩下的结果是什么。我们知道r必须是[Movie]类型,如果考虑一下,r应该是ms中满足谓词p的电影的列表。对于如何考虑这一点,我没有很好的解释,但是我能提供的最佳建议是,通过阅读和编写许多像这样的小递归函数,人们对如何解决这些问题有了直觉:

search p (m:ms) = if p m then p:r else r
  where r = search p ms

一种替代解决方案是使用前奏中的filter :: (a -> Bool) -> [a] -> [a]函数:

search = filter