0

我正在尝试将列表 ["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

我做错了什么,还是我错过了任何情况?

4

1 回答 1

1

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

第 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. 使您的函数具有多态性。您需要做的就是更改类型签名bagSingleItembagItems替换Char为类型变量并添加Eq ...约束:

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
...
于 2015-10-08T13:50:25.700 回答