将列表映射到类型

Map a list into a type

我正在尝试将列表 ["a"、"b"、"c"、"c"] 转换为 haskell 中的集合,比如:[ ("a",1),("b",1),("c",2)]。我不想使用地图。我的函数如下所示:

-- bagMyItem
bagMyItem :: Eq g => [g] -> Bag g -> Bag g
bagMyItem  (h:t) bag
     | h==q = (q,v+1):(listToBag t bag)  
     | null rBag = bag ++ [(h,1)]     
     | otherwise = (q,v):(listToBag (h:t) rBag)
     where ((q,v):rBag) = bag

我是不是做错了什么,还是我遗漏了任何案例?

以下是我对如何解决此问题的建议:

第 1 步:最初我会用具体类型编写函数。当您犯错误时,您会收到不那么晦涩的错误消息。稍后您可以返回并使函数多态。

第 2 步:让我们选择 Char 作为我们的具体类型。编写一个包含单个 Char:

的函数
type Bag g = [ (g,Int) ]

bagSingleItem :: Char -> Bag Char -> Bag Char
bagSingleItem c [] = ...
bagSingleItem c ( (d,v) : bag ) = ...

第 3 步:使用此函数编写一个包含整个项目列表的函数:

bagItems :: [Char] -> Bag Char -> Bag Char
bagItems [] bag = ...
bagItems (c:cs) bag =  ... bagSingleItem ...

第 4 步。使您的函数多态。您需要做的就是通过将 Char 替换为类型变量并添加 Eq ... 约束来更改 bagSingleItembagItems 的类型签名:

bagSingleItem :: Eq g => g -> Bag g -> Bag g
(definition remains the same)

bagItems :: Eq g => [g] -> Bag g -> Bag g
(definition remains the same)

或者 - 甚至更好 - 完全删除类型签名并让 ghci 使用 :t 命令告诉你它们是什么:

ghci> :t bagSingleItem
...
ghci> :t bagItems
...