使用高过滤功能和递归

时间:2014-04-02 02:37:33

标签: haskell recursion functional-programming

我需要在Haskell 中编写2个函数,每个函数使用2个不同的方法(高滤波器和递归)。

我有2个元组来执行此操作:

  

材料(Model, Price, Accesories) :: (String, Int, [(String, Int)])

     

Accesory (Name, Price) :: (String, Int)

  • 第一个函数totalPrice接收Material元组并具有 返回总价格(材料价格+配件价格)

    示例:

      

    主> totalPrice(“表”,150,[(“椅子”,100),(“椅子”,5)])

         

    返回:totalPrice = 255

    我已经通过递归制作了它:

    totalPrice (_,x,l) = x + sum l
    sum [] = 0
    sum (t:ts) = snd t + sum ts
    

    但我不知道如何使用高过滤功能。

  • 第二个函数 expensiveMaterialsPrice 会收到一个列表 材料并且只能返回总价格的总和 昂贵的材料。 A

2 个答案:

答案 0 :(得分:3)

您根本不需要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

它根本不会改变代码的含义,别名是可以互换的(即PriceInt是相同的类型,只是名称不同),但它确实减少了输入和制作你的意图很清楚。

答案 1 :(得分:0)

通过使用高阶函数实现

totalPrice

totalPrice (_,x,l) = x + (sum $ map snd l)

expensiveMaterialsPrice

expensiveMaterialsPrice ms = sum $ map totalPrice $ filter isExpensive ms
    where isExpensive m = totalPrice m > 1500