我对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^^"