Haskell 将函数应用于项目列表

Haskell 将函数应用于项目列表,haskell,functional-programming,Haskell,Functional Programming,我已经定义了一个函数f,该函数返回存储在类型为[(String,String,Int)]的价格列表中的项目x的price 我必须将此函数应用于项目列表,但我被卡住了。这可以用地图吗?我想不出来 (唯一可以使用递归的函数是f) 编辑。一些例子稍微澄清一下 pricesList = [("apple","ipod",100),("apple","iphone",200),("samsung","galaxy",200)] moneySpent = [("harry",1985,"apple",["i

我已经定义了一个函数
f
,该函数返回存储在类型为
[(String,String,Int)]的价格列表中的项目
x
price

我必须将此函数应用于项目列表,但我被卡住了。这可以用地图吗?我想不出来

(唯一可以使用递归的函数是f)

编辑。一些例子稍微澄清一下

pricesList = [("apple","ipod",100),("apple","iphone",200),("samsung","galaxy",200)]
moneySpent = [("harry",1985,"apple",["iphone","ipod"]),("george",1983,"samsung",["galaxy"])]

*Main> f "apple" "iphone" pricesList
200
我需要知道一个人定义一个新函数花了多少钱,比如说
spentBy
(并在其中使用
f

到目前为止我所做的:

itsThePerson name (n,_,_,_) = name == n

infoFrom name = (head . filter (itsThePerson name)) moneySpent

brand (_,_,b,_) = b
product (_,_,_,p) = p

brandPerson = brand . infoFrom
productPerson = product . infoFrom
是否可以将
map
与功能
f
一起使用,以了解一个人购买的产品的价格总和

(函数
f
将是函数
itemPrice


我想的方向正确吗?

假设你有一个三参数函数:

f :: a -> b -> c -> d
c
值的列表-
列表::[b]
。假设我们希望对列表中的每个项目应用
f
,并使用固定的第一个和第二个参数。所以我们可以这样做:

map (f x y) list
其中
x::a
y::b

与您的案例唯一不同的是参数的顺序。对于此类问题,请使用
flip

flip :: (a -> b -> c) -> (b -> a -> c)

--original function
f :: a -> b -> c -> d

--partial application
f x :: b -> c -> d

-- flip
flip (f x) :: c -> b -> d

--partial application again
(flip (f x) y) :: b -> d

map (flip (f x) y) list :: [d]

在您的情况下,它可能会导致类似于
map(flip(fa)prices)list

的结果,假设您有一个三参数函数:

f :: a -> b -> c -> d
c
值的列表-
列表::[b]
。假设我们希望对列表中的每个项目应用
f
,并使用固定的第一个和第二个参数。所以我们可以这样做:

map (f x y) list
其中
x::a
y::b

与您的案例唯一不同的是参数的顺序。对于此类问题,请使用
flip

flip :: (a -> b -> c) -> (b -> a -> c)

--original function
f :: a -> b -> c -> d

--partial application
f x :: b -> c -> d

-- flip
flip (f x) :: c -> b -> d

--partial application again
(flip (f x) y) :: b -> d

map (flip (f x) y) list :: [d]

在您的情况下,它可能会导致类似于
map(flip(fa)prices)list

的结果。如果您为
f
提供了一个类型签名,那么您要做的事情就会更清楚。我假设
f
的第三个参数是
(item#,description,price)
的列表。例如:

priceList = [(1,"item 1", 1), (2,"item 2", 22), (3, "item 3", 333), (4, "item 4", 4444)]
那么我们计划绘制的列表必须如下所示:

list = [(1,"item 1"), (3,"item 3"), (4, "item 4")]
 f _ _ _ = error "item not found"
我们可以像这样映射
列表

map (\(itemId, desc) -> f itemId desc priceList) list
您可以编写
f
来获取两个参数,将前两个参数组合成一个元组
f(a,x)((a1,x1,price):ys)
。您只需要
映射f列表

最后,您还没有处理价格不在列表中的情况。你可以这样做:

list = [(1,"item 1"), (3,"item 3"), (4, "item 4")]
 f _ _ _ = error "item not found"

如果您为
f
提供了一个类型签名,那么您要做的事情就会更清楚。我假设
f
的第三个参数是
(item#,description,price)
的列表。例如:

priceList = [(1,"item 1", 1), (2,"item 2", 22), (3, "item 3", 333), (4, "item 4", 4444)]
那么我们计划绘制的列表必须如下所示:

list = [(1,"item 1"), (3,"item 3"), (4, "item 4")]
 f _ _ _ = error "item not found"
我们可以像这样映射
列表

map (\(itemId, desc) -> f itemId desc priceList) list
您可以编写
f
来获取两个参数,将前两个参数组合成一个元组
f(a,x)((a1,x1,price):ys)
。您只需要
映射f列表

最后,您还没有处理价格不在列表中的情况。你可以这样做:

list = [(1,"item 1"), (3,"item 3"), (4, "item 4")]
 f _ _ _ = error "item not found"
修改后的答复: 你要解决的总体问题

  • 给定一个函数f,它接受'itemId','itemName'和'priceList' 并返回一个价格
  • 您需要一个函数,该函数使用f从[(itemId,itemName)]列表返回价格列表
就类型签名而言,给出:

f :: String -> String -> [(String, String, Int)] -> Int
你想要:

myLookup :: (String -> String -> [(String, String, Int)] -> Int) -> 
                [(String, String, Int)] -> [(String, String)] -> [Int]
其中第一个参数是查找函数
f
,一个priceList和一个itemList,输出是一个价格列表

myLookup f priceList itemList = map (\(itemId, itemName) -> 
                                          f itemId itemName priceList)
                                    itemList
map
的第二个参数是lambda,它从itemList中提取两个属性,并使用
f
查找值

修改后的答案: 你要解决的总体问题

  • 给定一个函数f,它接受'itemId','itemName'和'priceList' 并返回一个价格
  • 您需要一个函数,该函数使用f从[(itemId,itemName)]列表返回价格列表
就类型签名而言,给出:

f :: String -> String -> [(String, String, Int)] -> Int
你想要:

myLookup :: (String -> String -> [(String, String, Int)] -> Int) -> 
                [(String, String, Int)] -> [(String, String)] -> [Int]
其中第一个参数是查找函数
f
,一个priceList和一个itemList,输出是一个价格列表

myLookup f priceList itemList = map (\(itemId, itemName) -> 
                                          f itemId itemName priceList)
                                    itemList

map
的第二个参数是lambda,它从itemList中提取两个属性,并使用
f
查找值

我可以解决我的问题:

f a x ((a1, x1, price):ys) | a == a1 && x == x1 = price
                           | otherwise = f a x ys
使用了新功能
f2

f2 a x = f a x pricesList
然后


我可以解决我的问题:

f a x ((a1, x1, price):ys) | a == a1 && x == x1 = price
                           | otherwise = f a x ys
使用了新功能
f2

f2 a x = f a x pricesList
然后


完全不清楚你想做什么。如果你有作业,试着逐字引用。如果您试图执行某项现实任务,请描述该任务。如果我理解您的意图,
f
是一个查找项目价格的函数,
list
是您要查找价格的项目列表。对吗?@mhwombat是的,对。我需要将函数
f
应用于项目列表,而不仅仅是一个项目。这是否可能使用map?将来,与其重新编写问题,不如在底部添加任何澄清。
map
获取一个列表和一个转换函数,并返回一个按元素转换的列表。你有什么样的名单?你想得到什么样的列表?完全不清楚你想做什么。如果你有作业,试着逐字引用。如果您试图执行某项现实任务,请描述该任务。如果我理解您的意图,
f
是一个查找项目价格的函数,
list
是您要查找价格的项目列表。是吗?@mhwombat是的,我