Haskell 使用列表显示的新实例声明

Haskell 使用列表显示的新实例声明,haskell,Haskell,我是haskell的新手,我的任务是为我定义的数据类型定义一个新的Show实例声明,但我正在努力。我一直在搜索这里已经回答的问题,但我没有得到任何结果,这是如此令人沮丧,我创建了一个帐户,只是为了解决这个问题 假设我声明了两种新的数据类型 data shoppingList = shoppingList { name :: String , items :: [Item]} data Item = Food String Floa

我是haskell的新手,我的任务是为我定义的数据类型定义一个新的Show实例声明,但我正在努力。我一直在搜索这里已经回答的问题,但我没有得到任何结果,这是如此令人沮丧,我创建了一个帐户,只是为了解决这个问题

假设我声明了两种新的数据类型

data shoppingList = shoppingList { name :: String
                                 , items :: [Item]}
data Item = Food String Float | Clothes String
我需要做一个Show的实例声明,这样任何购物清单都会看起来像
名称:dog\u food->衣服->许多苹果->衣服,这取决于它是食物还是衣服。这意味着,如果是食物,它会打印食物的名字,如果是衣服,它每次只打印“衣服”

我所能做的就是

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”:[“狗粮”,衣服,“许多苹果”,衣服]
,这不是我需要的


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

据我所知,你已经得到了结肠左边的部分;你所需要的只是右边的部分

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

使用
Data.list
(文档化)中的
interlate
,可以轻松完成此特定任务(在列表中插入字符串)

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

实例显示ShoppingList,其中
show(ShoppingList n l)=show n++“:“++”插入“->”(地图显示l)

作为旁注,
name
将是一个
Float
,而不是
字符串
(或类似),这是违反直觉的(至少对我来说)。你可能应该考虑改变它。

不要忘记将类型和值构造函数的初始字母大写;p>


像这样滥用
Show
实例通常被认为是不好的形式,因为
Show
应该生成一个数据结构的字符串表示,它尽可能接近在Haskell源代码中手动编写数据结构的方式。或者这是一个家庭作业问题,你必须使用
Show
实例?@K.a.Buhr这是一个家庭作业问题,我必须使用它!非常感谢你,你解除了我在这项工作中前进的障碍!我感激不尽!你是对的,名字作为
字符串
比作为
浮点
更好,但这只是我举的一个例子,因为我需要知道的是如何像那样呈现列表。谢谢大家!@斯坦鲁纳很高兴能帮上忙。
import Data.List (intercalate)
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^^"