【问题标题】:Haskell recursive find FunctionHaskell递归查找函数
【发布时间】:2015-11-24 20:43:50
【问题描述】:

我有超市库存清单的代码:

type Barcode = Int
type Name = String
type Price = Int
data Inventory = Inventory Barcode Name Price deriving (Eq, Ord, Show)

marktInventar :: [(Int,String,Int)]
marktInventar = [ (321, "Salz",     35)
                , (432, "Butter",   95)
                , (531, "Milch",    85)
                , (235, "Eier",    145)
                , (246, "Schmalz", 245)
                , (642, "Mehl",    110)
                , (528, "Safran",  249)
                , (395, "Wurst",   345)
                , (294, "Kaese",   215)
                , (178, "Tomate",   45)
                , (378, "Banane",   75)
                , (938, "Orange",   65)
                , (491, "Kiwi",     95)
                ]

我只是给了名单,其余的都是我自己做的,我希望它是正确的。 现在我应该构建一个函数 findArticle,在其中输入条形码并获取产品的名称和价格。它应该是一个递归函数,在列表中搜索匹配的条形码。但是我该怎么做呢?

感谢您的帮助

【问题讨论】:

  • 您需要自己写findArticle,作为家庭作业,还是您需要解决的真正问题?如果是后者,您应该可以使用Data.List.lookup,前提是您可以预处理您的库存,使其具有[(Int, (String, Int)] 类型;或者直接使用Data.List.find
  • 如果有多个产品带有给定的条形码,或者没有带有给定条形码的产品(例如,如果市场被抢劫并且没有产品剩下)会发生什么?跨度>

标签: haskell recursion


【解决方案1】:

您不需要自己编写递归函数 -- Data.List 已经导出了带有此签名的函数 find

find :: Foldable t => (a -> Bool) -> t a -> Maybe a

给定一个条形码bc 进行查找,您的情况下的谓词可以是

\(bc', _, _) -> bc' == bc

如果找到条形码,结果将为Just (_, name, price),否则为Nothing

【讨论】:

    【解决方案2】:

    这是一个递归版本,但请记住它不是最佳选择:

    findIt :: Barcode -> [Inventory] -> (Name, Price)
    findIt code [] = ()
    findIt code ((Inventory bc n p):xs) | code == bc = (n, p)
                                        | otherwise  = findIt code xs
    

    【讨论】:

    • 感谢您的回答。我想这就是我要找的东西,但如果我尝试使用它,我会在 findit 上得到一个解析错误。
    • @MOHAWK 检查你的缩进。
    • 因为我在工作,所以无法测试它(这里没有 haskell repl :/)
    【解决方案3】:

    您可能想要命名您的记录样式参数,命名类型以使其与单个库存项目匹配,并使用类型 Inventory 来反映整个库存(例如项目列表):

    type Barcode = Int
    type Name = String
    type Price = Int
    data InventoryItem = InventoryItem { barcode :: Barcode
                                       , name    :: Name
                                       , price   :: Price
                                       }
                         deriving (Eq, Ord, Show)
    type Inventory = [(Barcode, InventoryItem)]
    

    然后您可以将您的marktInventar 转换为Inventory

    inventory :: Inventory
    inventory = map (\(bc, n, p) -> (bc, InventoryItem bc n p)) marktInventar
    

    并且,正如Cactus 建议的那样,将Data.List.lookup 用于您的函数findArticle

    findArticle :: Barcode -> Inventory -> Maybe InventoryItem
    findArticle = lookup
    

    【讨论】:

    • 谢谢你的回答,但是当我这样做时,我得到了错误:No instance for (Show (Inventory -> Maybe InventoryItem)) 由于在交互式 GHCi 的 stmt 中使用“打印”而引起命令:打印出来对不起,我是个菜鸟,只是不明白这些类型。
    猜你喜欢
    • 2011-02-14
    • 2019-02-28
    • 1970-01-01
    • 2017-01-20
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 2020-11-13
    相关资源
    最近更新 更多