haskell - Haskell 电影搜索
问题描述
我是 Haskell 的新手,我有一个项目需要在列表中满足条件时给出 True,我已经创建了另一个函数来检查分数是否高于或导演是否相同但现在我需要合并这个条件在一起,但我被困住了,不知道该怎么做。
该功能需要为该测试用例返回 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
解决方案
好的,看来您走在正确的轨道上。您对搜索功能的类型有一个想法,所以让我们把它写下来:
search :: (Movie -> Bool) -> [Movie] -> [Movie]
让我们尝试从基本原理中弄清楚这一点。
第一个参数是一个函数。我们称它为predicatep
。这个函数我们无能为力。最明显的是将它应用到电影中,但到目前为止我们还没有。
第二个参数是电影列表。让我们对其进行模式匹配。第一种情况是[]
:
search p [] = (??)
好吧,我们需要在这里返回一个电影列表,我认为我们不应该凭空捏造一个,所以我们可能不应该返回一个。事实上,如果你搜索一个没有电影的列表,你肯定会得到什么。在这种情况下,我们不使用谓词参数,所以让我们写_
一下,你可以清楚地表明我们不使用它:
search _ [] = []
另一种情况是列表的头部和其余部分。让我们将电影m
的头部称为头部,按照惯例,尾部将被称为:ms
search p (m:ms) = (??)
至此,我们现在有了一个可以调用函数的电影p
,所以让我们这样做并考虑结果:
search p (m:ms) =
if p m
then (??)
else (??)
那么我们在这里做什么呢?如果p m
为真,那么我们应该m
在输出中包含,如果为假,那么我们不应该包含它。r
让我们调用result的其余输出:
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
推荐阅读
- python - Pyinstaller:FileNotFoundError:在“jaraco.text”中找不到“Lorem ipsum.txt”资源
- r - 从具有 2 列的数据框创建子集
- python - 正则表达式匹配最后一行的第一个元素
- python - Kivy 无响应且无法更改文本框中的文本
- python - Numpy:在一个方程中找到所需的值,使误差最小化
- c# - 如何在非 UWP C# 项目中访问 Windows.Gaming.Input?
- python - 来自 Airflow 数据库挂钩的 SQLAlchemy 引擎
- powershell - 搜索正在使用的 AD 扩展属性
- javascript - angular 9 的 Quickblox webrtc 视频通话在 iPhone 11 中不起作用
- javascript - 构建我的反应应用程序时,纱线构建显示空白页面?