我是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
答案 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