功能输入类型

neb*_*ffa 3 haskell

我正在大学学习Haskell - 这是我在业余时间做过的一个研讨会问题,你可能会猜到我正在努力解决Haskell中的类型问题.我已经完成了这个问题,但是没有答案发表但我仍然非常怀疑这是否是最好的方法.

以下是问题中提供的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_tag (Maybe Int) (Maybe String) (Maybe Font_color)
data Font_color
    = Colour_name String
    | Hex Int
    | RGB Int Int Int
Run Code Online (Sandbox Code Playgroud)

该问题要求构造一个Haskell函数'num_font_tags',它将计算这种HTML表示中的font_tag的所有实例.接下来是我的回答,这让我花了整整一个小时的时间将我的头贴在墙上,但它编译得很好,我认为这是一个解决方案:

num_font_tags :: HTML -> Int
num_font_tags [] = 0
num_font_tags (x:xs) = num_font_tag_single x + num_font_tags xs

num_font_tags_list :: [HTML] -> Int
num_font_tags_list [] = 0
num_font_tags_list (x:xs) = num_font_tags x + num_font_tags_list xs

num_font_tag_single :: HTML_element -> Int
num_font_tag_single (HTML_text _) = 0
num_font_tag_single (HTML_font _ html) = num_font_tags html
num_font_tag_single (HTML_p html) = num_font_tags html
num_font_tag_single (HTML_ul html) = num_font_tags_list html
num_font_tag_single (HTML_ol html) = num_font_tags_list html
Run Code Online (Sandbox Code Playgroud)

最初我以为我只需要第一个函数,但我遇到了问题,因为它只接受HTML类型,但后来又需要两个函数 - 一个接受[HTML]类型,一个接受HTML_element类型.

我是否真的需要这样做?或者我是通过3个功能来实现的.可以用一个吗?我的主要问题是 - 我是否遗漏了一些关于Haskell性质的内容,这会让这更简单?

Dan*_*her 6

您只需要一个这样的功能,其他功能可以简单地减少到

num_font_tag_single :: HTML_element -> Int
Run Code Online (Sandbox Code Playgroud)

summap.

如你所愿,你有

num_font_tags xs = sum $ map num_font_tag_single xs
Run Code Online (Sandbox Code Playgroud)

num_font_tag_list xs = sum $ map num_font_tags xs
                --   = sum . map num_font_tag_single $ concat xs
Run Code Online (Sandbox Code Playgroud)

您还可以从其他两个函数中派生剩余函数,因为您可以轻松地从单个值中获取列表,但无论如何您需要在某个时刻检查a HTML_element,因此最好num_font_tag_single建立基于哪个来构建.

你有

num_font_tag_single (HTML_font _ html) = num_font_tags html
Run Code Online (Sandbox Code Playgroud)

应该是

num_font_tag_single (HTML_font _ html) = num_font_tags html + 1
                                                        --  ^^^
Run Code Online (Sandbox Code Playgroud)

或者你可以简化功能num_font_tag_single _ = 0.

除此之外,这基本上是唯一的方法,无论你是否将包含HTML_elements resp的列表中的字体标签数量相加的函数命名.[HTML]或使用sum . map num_font_tag_singleresp.sum . map num_font_tag_single . concat主要取决于个人偏好,但由于目标是一个功能

num_font_tags :: HTML -> Int
Run Code Online (Sandbox Code Playgroud)

给它一个名字(并num_font_tags . concat在递归中使用)是很自然的.