我需要在Haskell中编写2个函数, 但每个函数有2个不同的方法(高过滤器和递归)。
我有2个元组来做到这一点:
材料是(Model, Price, Accesories) :: (String, Int, [(String, Int)])
Accesory是(Name, Price) :: (String, Int)
第一个函数totalPrice收到Material元组并且必须返回总价格(Material price + Accesories price)
例:
Main> totalPrice(“表”,150,[(“椅子”,100),(“椅子”,5)])
返回:totalPrice = 255
我已经通过递归制作了它:
totalPrice (_,x,l) = x + sum l sum [] = 0 sum (t:ts) = snd t + sum ts但我不知道如何使用高过滤功能。
第二个功能昂贵的材料价格收到材料清单,并且只返回昂贵材料总价的总和。 一个
I need to code 2 functions in Haskell but with 2 differents methods each (high-filter and recursion).
I have 2 tuples to do this:
Material is (Model, Price, Accesories) :: (String, Int, [(String, Int)])
Accesory is (Name, Price) :: (String, Int)
The first function totalPrice receives the Material tuple and has to return the total price (Material price + Accesories price)
Example:
Main> totalPrice ("Table",150,[("Chair",100),("Chair",5)])
Returns: totalPrice = 255
I already made it with recursion:
totalPrice (_,x,l) = x + sum l sum [] = 0 sum (t:ts) = snd t + sum tsbut I don't know how to do it with high-filter functions.
The second function expensiveMaterialsPrice receives a list of Materials and has to return only the sum of the total prices of the expensive materials. A
最满意答案
你根本不需要过滤totalPrice的过滤器,我认为你正在寻找术语“高阶函数”。 相反,您只需要一个功能来访问配件的价格:
accessoryPrice :: (String, Int) -> Int accessoryPrice (_, price) = price然后,您可以轻松地将配件列表转换为价格列表:
accessoryPrices :: [(String, Int)] -> [Int] accessoryPrices accessories = map accessoryPrice accessories现在,您可以使用此输出的总和来获得总配件价格
totalAccessoryPrice :: [(String, Int)] -> Int totalAccessoryPrice accessories = sum $ accessoryPrices accessories我会留给你把它整合到你当前的代码中=)
有趣的是, accessoryPrice只是一种更具体的snd形式,你可以用更短的形式编写这段代码
totalAccessoryPrice = sum . map snd但就你的意图而言,这一点还不太清楚。 我强烈建议现在使用更详细的表格,它有助于将问题分解为离散的步骤来解决,而不是试图立即解决整个解决方案。
对于expensiveMaterialsPrice ,您将需要使用过滤器。 在这种情况下,你应该创建一个函数isExpensive :: (String, Int, [(String, Int)]) -> Bool来指示材料是否昂贵:
isExpensive :: (String, Int, [(String, Int)]) -> Bool isExpensive material = totalPrice material > 1500然后,您可以使用isExpensive作为要filter的谓词(第一个参数)。
可能有用的东西是创建一些类型别名:
type Name = String type Price = Int type Accessory = (Name, Price) type Material = (Name, Price, [Accessory]) accessoryPrice :: Accessory -> Price -- same definition accessoryPrices :: [Accessory] -> [Price] -- same definition totalAccessoryPrice :: [Accessory] -> Price -- same definition totalPrice :: Material -> Price -- your definition here isExpensive :: Material -> Bool -- same definition它根本不会改变代码的含义,别名是可以互换的(即Price和Int是相同的类型,只是名称不同),但它确实减少了输入并使你的意图非常清晰。
You don't need a filter for totalPrice at all, I think you're looking for the term "higher order function". Instead, you just need a function to access the price of an accessory:
accessoryPrice :: (String, Int) -> Int accessoryPrice (_, price) = priceThen you can easily transform a list of accessories into a list of prices:
accessoryPrices :: [(String, Int)] -> [Int] accessoryPrices accessories = map accessoryPrice accessoriesNow you can use sum on the output of this to get the total accessory price
totalAccessoryPrice :: [(String, Int)] -> Int totalAccessoryPrice accessories = sum $ accessoryPrices accessoriesAnd I'll leave it to you to integrate this into your current code =)
Fun fact, accessoryPrice is just a more specific form of snd, and you could instead write this code in the much shorter form
totalAccessoryPrice = sum . map sndBut this is far less clear as to your intentions. I would highly recommend using the more verbose form for now, it helps to break the problem into discrete steps to solve instead of trying to tackle the entire solution at once.
For the expensiveMaterialsPrice, you will want to use a filter. In this case, you should make a function isExpensive :: (String, Int, [(String, Int)]) -> Bool to indicate if a material is expensive or not:
isExpensive :: (String, Int, [(String, Int)]) -> Bool isExpensive material = totalPrice material > 1500Then you can use isExpensive as the predicate (the first argument) to filter.
Something that might help would be to create some type aliases:
type Name = String type Price = Int type Accessory = (Name, Price) type Material = (Name, Price, [Accessory]) accessoryPrice :: Accessory -> Price -- same definition accessoryPrices :: [Accessory] -> [Price] -- same definition totalAccessoryPrice :: [Accessory] -> Price -- same definition totalPrice :: Material -> Price -- your definition here isExpensive :: Material -> Bool -- same definitionIt doesn't change the meaning of your code at all, aliases are interchangeable (i.e. Price and Int are the same type, just with different names), but it does reduce typing and makes your intentions very clear.
更多推荐
发布评论