使用需要多个输入的筛选器-Haskell

使用需要多个输入的筛选器-Haskell,haskell,Haskell,我对Haskell比较陌生,在过去的几周里一直在努力学习它,但一直停留在过滤器和谓词上,我希望能在理解方面得到帮助 我遇到了一个问题,我有一个元组列表。每个元组由一个(songName、songArtist、saleQty)组成,am需要根据输入songName和songArtist的用户从该列表中删除元组 返回结果时,我知道我可以在返回结果时使用Filter函数删除元组。我一直在用LYAH阅读它。它教会我必须使用谓词(另一个函数)来过滤结果。这让我措手不及,因为我了解到过滤器函数的类型为(a-

我对Haskell比较陌生,在过去的几周里一直在努力学习它,但一直停留在过滤器和谓词上,我希望能在理解方面得到帮助

我遇到了一个问题,我有一个元组列表。每个元组由一个
(songName、songArtist、saleQty)
组成,am需要根据输入songName和songArtist的用户从该列表中删除元组

返回结果时,我知道我可以在返回结果时使用
Filter
函数删除元组。我一直在用LYAH阅读它。它教会我必须使用谓词(另一个函数)来过滤结果。这让我措手不及,因为我了解到
过滤器
函数的类型为
(a->Bool)->[a]->[a]
,这意味着
过滤器
的输入需要是布尔值,谓词的输出需要是布尔值,这样就可以将其输入到
过滤器

这是一个问题,因为要从列表中筛选结果,我需要在递归遍历结果时将songName和SongArtister(两者都是字符串类型)输入到谓词,并将songName和SongArtister输出到
过滤器
,让它知道需要从列表中删除哪个确切的元组

我是走错了路还是有更好的办法

我了解到一个过滤函数的类型是
(a->Bool)->[a]->[a]

接受两个参数,一个带有签名
a->Bool
的谓词和一个项目列表,它返回满足谓词的项目列表。因此谓词是第一个参数

这意味着我对
过滤器的输入必须是
布尔值

否第一个参数的类型为
a->Bool
,因此它是一个将项目
a
映射到
Bool
的函数,因此是一个谓词

例如,您可以创建一个函数来检查
songName
songTitle
是否与以下内容匹配:

filterSales :: String -> String -> [(String, String, Int)] -> [(String, String, Int)]
filterSales artist title items = filter p items
    where p (artist', title', _) = artist == artist' && title == title'
filterSales::String->String->[(String,String,Int)]->[(String,String,Int)]
filterSales艺术家标题项=筛选p项
式中p(艺术家,头衔),_)=艺术家==艺术家'&&title==头衔'

因此,
p
就是谓词,一个将三元组映射到布尔值的函数。如果前两项分别等于
artist
title
,谓词
p
将返回三元组的
True
;毕竟,两种解释不可能比一种解释更糟糕,对吗

filter
对您的期望是一个函数,它会告诉您一件事——我是否应该将给定的元素保留在结果集合中

该函数的类型是
(a->Bool)
,我们称之为谓词

在您的具体情况下,假设

type SongEntry = (SongName, SongArtist, SaleQty)
这将是一个类型为
歌曲输入->Bool
的函数。现在,可能有很多这样的功能。。。也许你想要超过100次的销售

hasMoreThan100Sales :: SongEntry -> Bool
hasMoreThan100Sales (_, _, sales) = sales > 100
要使用它:

filter hasMoreThan100Sales songs
这应该很容易。如果我们想要的不仅仅是销售怎么办?这就是哈斯克尔的咖喱在默认情况下真正闪耀的地方。我们可以添加一个附加参数:

hasMoreThanNSales :: Int -> SongEntry -> Bool
我们也可以将其理解为
Int->(songinentry->Bool)
。在这一点上,实施是严格的:

hasMoreThanNSales n (_, _, sales) = sales > n
关键的是,要获得之前的“100”函数,我们只需要应用它:

hasMoreThanNSales 100 :: SongEntry -> Bool
这是我们需要与
过滤器一起使用的类型:

filter (hasMoreThanNSales 100) songs

在这一点上,您应该对它有足够的了解,可以编写您自己的谓词,以任何您想要的方式对其进行参数化


哦,还有一件事可能会让人困惑
的销售额超过100个
是一个谓词
hasMoreThanNSales
不是,除非您使用一个值(例如100)
(hasMoreThanNSales 100)
是一个谓词。

因此p本身不是一个有其自身功能的函数,但是,只需根据示例中使用的模式匹配结果返回true或false?@Chadderz:
p
是一个函数,它需要一个3元组
(艺术家、标题)
,如果
artist'
title'
分别等于
artist
title,则返回
Truee
False