0

我现在正在做这个作业,但我不知道。有人可以帮助我吗?

给定以下用于表示 HTML 的数据类型:

type HTML = [HTML_element]
data HTML_element = HTML_text String
                  | HTML_font Font_tag HTML
                  | HTML_p HTML
                  | HTML_ul [HTML]
                  | HTML_ol [HTML]

data Font_tag = Font_size Int
              | Font_face String
              | Font_color Font_color

data Font_color = Colour_name String
                | Hex Int
                | RGB Int Int Int

编写一个 Haskell 函数:

strip_font_tags :: HTML -> HTML

这会删除所有字体标签,并用它们的 HTML 内容替换它们。

4

2 回答 2

5

我认为这里的其他人都错过了练习的重点。这是我解释问题后的思考过程;也许这可以指导你一点。

我想考虑一次操作一个HTML_element,所以我想要一个在某个时候有类型的函数HTML_element -> ???;弄清楚???可能是什么将是巨大的第一步。第一个刺是选择HTML_elementfor ???,但这并不完全有效,因为字体标签的内容是HTML,而不是HTML_element。嗯……HTML又是什么?啊,是的,type HTML = [HTML_element]!所以,实际上,我可以HTML在每种情况下返回一个;在非字体情况下,我可以将单个元素包装在单例列表中。

嗯,但现在呢?我想知道现在我已经编写了每个元素的函数,是否有一个函数可以满足我的需求......

于 2012-08-20T17:56:06.927 回答
0

好吧,最简单的方法是HTML_element用另一个替换HTML_element——这是一个结构保持转换,你可能会稍微改变你的数据,编写一个Functor实例,然后就使用fmap——你的映射是“如果是HTML_font _ x,则返回例如HTML_p x;如果不是,按原样返回”。

这是用 SYB 表示的:

{-# LANGUAGE DeriveDataTypeable #-}
import Data.Generics

data Element
    = Text String
    | Font [Element]
    | Para [Element]
    deriving (Show, Typeable, Data)

-- replace Font with Para
replace' :: Element -> Element
replace' (Font x) = Para x
replace' x = x

-- top-level transformation
-- replace this with manual recursion and you're set
replace :: Element -> Element
replace = everywhere (mkT replace')

example =
    Para [
        Text "1",
        Font [
            Text "2.1",
            Para [
                Text "2.2.1",
                Font [Text "2.2.2"]
            ]
        ],
        Text "3"
    ] 

在 GHCi 中:

[*Main]
> replace example
Loading package syb-0.3.6.1 ... linking ... done.
Para [Text "1",Para [Text "2.1",Para [Text "2.2.1",Para [Text "2.2.2"]]],Text "3"]
it :: Element

如果您想完全消除这些元素,您可以将所有内容映射到列表中,然后将它们连接起来。试着自己弄清楚。

于 2012-08-20T17:26:55.650 回答