我有一个数据类型" Cake"
*data Cake = EmptyBox | Food { name :: String
, flavors :: [Cake]} deriving( Read, Eq)*
instance Show Cake where
show cake = prints cake where
prints (Food name []) = name ++ "\n"
我想打印这样的蛋糕(每个蛋糕都有不同的口味)
Cake1
Chocolate
Nutella
Strawberry
Cake2
Chocolate
Vanilla
Cake3
但是我得到了错误,不起作用!我该怎么办?
答案 0 :(得分:2)
自prints :: Cake -> String
和flavors :: [Cake]
以来,我们知道
map prints flavors :: [String]
但是这与使用它的上下文没有关系,因为在
中" " ++ expr
" "
显然是String
,因此我们希望expr
为String
,而不是[String]
。
要解决此问题,您应该编写或查找以某种方式将[String]
转换为String
的函数 - 此类型有许多候选行为,因此您应该决定您的行为想要,然后找到一种方法来实现这种行为。
答案 1 :(得分:0)
对于测试数据,我使用了:
cake1 = Food{name="Cake1"
,flavors=[Food{name="Chocolate"
,flavors=[]}
,Food{name="Nutella"
,flavors=[Food{name="Strawberry"
,flavors=[]}]}]}
cake2 = Food{name="Cake2"
,flavors=[Food{name="Chocolate"
,flavors=[]}
,Food{name="Vanilla"
,flavors=[]}]}
cake3 = Food{name="Cake3"
,flavors=[]}
并将Show Cake
写为unlines
,其中包含Cake -> [String]
instance Show Cake where
show = unlines . prints where
prints :: Cake -> [String]
prints EmptyBox = []
prints (Food s []) = [s] -- a Food with no subflavors
prints (Food s fs) = s:concatMap (map (" "++) . prints) fs
最后一行通过将Food
映射到s
,然后映射{{1}来处理名称为fs
的{{1}}和风格prints
的一般情况在该地图中的每个子列表上,并将它们连接在一起。
fs
每个连续级别的味道都会增加额外的缩进程度(这就是(" "++)
的含义)。我们可以测试一下:
(" "++) :: String -> String
map (" "++) :: [String] -> [String]
map (" "++) . prints :: Cake -> [String]
map (map (" "++) . prints) :: [Cake] -> [[String]]
concat . map (map (" "++) . prints) :: [Cake] -> [String]
concatMap = concat . map
concatMap (map (" "++) . prints) :: [Cake] -> [String]