如何融合(某种合并)Haskell 列表中的某些项目[重复]

问题描述 投票:0回答:1

我在 Haskell 中创建了以下三种类型:

type Product = (Int, String, Float)

type Order = (Product, Int)

type Purchase = [Order]

想法是每个

Product
都有一个ID(
Int
),一个名字(
String
)和一个价格(
Float
)。
Order
是给定
Int
的某个离散量 (
Product
)。
Purchase
Order
s 的列表。

有了这个,我必须创建一个函数,它接受两个

Purchase
然后融合它们,返回另一个
Purchase
作为回报。例如,如果输入是
[(product1, 2), (product1, 3), (product2, 4), (product2, 5), (product3, 10)]
,那么输出应该是
[(product1, 5), (product2, 9), (product3, 10)]
。换句话说,它删除所有重复的
Order
s,对所有数量求和,并输出结果“融合”
Purchase
.

这是我目前拥有的功能。它不起作用,Haskell 指出了几个

Couldn't match type
错误。

fusePurchases :: Purchase -> Purchase -> Purchase
fusePurchases p1 p2 = let productsIds = nub [productId | (aproduct, _) <- p1 ++ p2, let productId = fst aproduct] in [(aproduct, sum [snd p | p <- p1 ++ p2, fst (fst p) == productId])
      | productId <- productsIds, let aproduct = head [prod | prod <- map fst (p1 ++ p2), fst prod == productId]]

有什么问题吗?应该做哪些改变?什么是操作函数?

谢谢!

我尝试创建一个单一的功能,并使用列表理解将产品合并到一个具有独特元素的列表中,其中每个

Order
的所有数量的总和根据具有相同
Order
的其他
Product
s求和.

haskell list-comprehension
1个回答
0
投票

第一个错误:

MergeOrders.hs:10:107-114: error:
    • Couldn't match type: (Int, String, Float)
                     with: (a1, b1)
      Expected: (a1, b1)
        Actual: Product
    • In the first argument of ‘fst’, namely ‘aproduct’
      In the expression: fst aproduct
      In an equation for ‘productId’: productId = fst aproduct
    • Relevant bindings include
        productId :: a1 (bound at MergeOrders.hs:10:91)
   |
10 | fusionPurchases p1 p2 = let productsIds = nub [productId | (aproduct, _) <- p1 ++ p2, let productId = fst aproduct] in [(aproduct, sum [snd p | p <- p1 ++ p2, fst (fst p) == productId])
   |                                                                                                           ^^^^^^^^

出现是因为

aProduct
的类型是
Product
,它是一个三元组
(Int, String, Float)
,但您已尝试将函数
fst
应用于它,而
fst
仅适用于对。在 Haskell 中,将
fst
应用于一对作品:

> fst (1,2)
1

但是将它应用于三元组不会:

> fst (1,2,3)

<interactive>:1:5: error:
    • Couldn't match expected type: (a, b0)
                  with actual type: (a0, b1, c0)
    • In the first argument of ‘fst’, namely ‘(1, 2, 3)’
      In the expression: fst (1, 2, 3)
      In an equation for ‘it’: it = fst (1, 2, 3)
    • Relevant bindings include it :: a (bound at <interactive>:1:1)

其他两个错误都是由类似的问题引起的。在每种情况下,您都试图将

fst
应用于
Product
三元组。

您可能会发现定义

fst3

fst3 :: (a, b, c) -> a
fst3 (a, _, _) = a

有了这个定义,下面的类型检查就可以了:

fusionPurchases :: Purchase -> Purchase -> Purchase
fusionPurchases p1 p2 
  = let productsIds = nub [ productId | (aproduct, _) <- p1 ++ p2
                          , let productId = fst3 aproduct] 
    in [ (aproduct, sum [snd p | p <- p1 ++ p2, fst3 (fst p) == productId])
       | productId <- productsIds
       , let aproduct = head [ prod | prod <- map fst (p1 ++ p2)
                             , fst3 prod == productId]]
© www.soinside.com 2019 - 2024. All rights reserved.