实例显示haskell

时间:2017-11-21 21:45:30

标签: haskell

我有一个数据类型" 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

但是我得到了错误,不起作用!我该怎么办?

2 个答案:

答案 0 :(得分:2)

prints :: Cake -> Stringflavors :: [Cake]以来,我们知道

map prints flavors :: [String]

但是这与使用它的上下文没有关系,因为在

" " ++ expr

" "显然是String,因此我们希望exprString,而不是[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]