首页 > 解决方案 > 带有列表的 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 还是 Clothes。这意味着,如果是 Food,它会打印给食物起的名字,如果是 Clothes,它每次只打印“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],这不是我需要的。

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

标签: haskell

解决方案


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

正如你所指出的,show不做你想做的事——这意味着你必须自己做这个字符串操作。

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

import Data.List (intercalate)

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

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

作为旁注,它是违反直觉的(至少对我而言)name是 aFloat而不是 a String(或类似的)。你可能应该考虑改变它。


推荐阅读