带有列表的Show的新实例声明



我对haskell还很陌生,我的任务是为我定义的数据类型定义一个新的Show实例声明,但我很吃力。我一直在这里搜索已经回答过的问题,但我一无所获,我创建了一个帐户来解决这个问题,这让我非常沮丧。

想象一下,我已经声明了两种新的数据类型,比如

data shoppingList = shoppingList { name :: String
, items :: [Item]}
data Item = Food String Float | Clothes String

我需要做一个Show的实例声明,这样任何shoppingList都会看起来像name: dog_food -> CLOTHES -> many_apples -> CLOTHES,这取决于它是Food还是Clothings。这意味着,如果是Food,它会打印出食物的名字,如果是Clothings,它每次都会打印"Clothes"。

我能做的最好的事情就是

instance Show shoppingList where
show (shoppingList n l) = show n ++ ": " ++ show l
instance Show Item where
show (Food n _) = show n
show (Clothes_) = "CLOTHES"

然而,这不是我想要的最终结果,因为它打印的是类似"list1": ["dog_food",CLOTHES,"many_apples",CLOTHES]的东西,而这不是我需要的。

这个例子看起来可能有点愚蠢,但它表明了我的大问题。有人能帮我吗?

据我所知,您已经得到了冒号左侧的部分;你只需要右边的部分。

正如您所注意到的,show不能做您想做的事情——这意味着您必须自己做这个字符串操作。

这个特殊的任务(在列表中插入字符串(可以很容易地使用Data.List中的intercalate(此处记录(。

import Data.List (intercalate)

然后,ShoppingList的实例声明(注意大写字母S(如下:

instance Show ShoppingList where
show (ShoppingList n l) = show n ++ ": " ++ intercalate " -> " (map show l)

顺便说一句,name将是Float而不是String(或类似的(,这是违反直觉的(至少对我来说(。你可能应该考虑改变这一点。

不要忘记将类型和值构造函数的首字母大写;(

import Data.List
data ShoppingList = ShoppingList { name :: String
, items :: [Item]}
data Item = Food String Float | Clothes String
instance Show Item where
show (Food a _) = a
show (Clothes _) = "CLOTHES"
instance Show ShoppingList where
show a = let listName = name a
listItems = intercalate " -> " (map show $ items a)
in listName ++ ": " ++ listItems
-- use "show yourShoppingListName" to let the magic happen^^"

最新更新