我现在正在做这个功课,但我不知道。有人能帮助我吗?
给出以下用于表示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内容。
答案 0 :(得分:5)
我认为这里的其他人都错过了练习的重点。在解释问题之后,这是我的思考过程;也许这可以指导你一点。
我想考虑一次在一个HTML_element
上运行,所以我想要一个在某个时候具有HTML_element -> ???
类型的函数;搞清楚???
可能是什么将是一个巨大的第一步。第一个尝试是为HTML_element
选择???
,但这不太有用,因为字体标记的内容是HTML
,而不是HTML_element
。嗯......再次HTML
是什么?啊,是的,type HTML = [HTML_element]
!所以,实际上,我可以在每种情况下返回HTML
;在非字体情况下,我可以将单个元素包装在单个列表中。
答案 1 :(得分: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
如果要完全消除这些元素,您可以将所有内容映射到列表中,然后将它们连接起来。试着自己搞清楚。