无法穿插" "和unwords被用作彼此的替代品?

时间:2015-07-19 06:39:36

标签: haskell blaze-html

我试图改写:

return $ renderHtml $ mconcat $ intersperse " " $ catMaybes links

哪种方法很好,进入:

return $ renderHtml $ mconcat $ unwords $ catMaybes links

但它正在回归:

Couldn't match type ‘Char’
               with ‘blaze-markup-0.7.0.2:Text.Blaze.Internal.MarkupM ()’
Expected type: H.Html
  Actual type: Char
In the second argument of ‘($)’, namely
  ‘mconcat $ unwords $ catMaybes links’
In the second argument of ‘($)’, namely
  ‘renderHtml $ mconcat $ unwords $ catMaybes links’
In a stmt of a 'do' block:
  return $ renderHtml $ mconcat $ unwords $ catMaybes links

我对Haskell来说还不是最好的,但我认为intersperse " "unwords只是替换掉了吗?

修改:最后,我想找出一种方法来使用unwords ...弄明白为什么它会给我错误以及我如何可以解决它是目标! =)

2 个答案:

答案 0 :(得分:9)

unwords :: [String] -> String功能仅适用于String个列表。您拥有的是MarkupM ()类型的值列表。

intersperse :: a -> [a] -> [a]之所以有效,是因为它适用于任何类型的列表。对于OverloadedStrings pragma," "值的类型为MarkupM(因为该类型具有IsString的实例)。 intersperse函数获取这些标记值的列表并在它们之间放置空格但仍返回标记值列表。最后,mconcat将列表加入到仍为MarkupM ()类型的单个值中。使用一些伪数据构造函数,您可以想象如下的值:

[Markup "foo", Markup "bar", Markup "baz"] -- returned by catMaybes links
[Markup "foo", Markup " ", Markup "bar", Markup " ", Markup "baz"] -- after intersperse
Markup "foo bar baz" -- after mconcat

在这种情况下,没有简单的方法让unwords能够工作,因为你没有字符串并且转换为字符串会失去一些好处。例如,将标记封装在适当的包装中可确保您不会生成格式不正确的HTML。

答案 1 :(得分:2)

如果您使用LANGUAGE OverloadedStrings,则可以使用的内容。

否则,请使用intersperse (text " ")代替intersperse " "

E.g:

{-# LANGUAGE OverloadedStrings #-}

import Text.Blaze.Html
import Text.Blaze.Renderer.String
import Data.Maybe
import Data.List
import Data.Monoid

foo links = renderHtml $ mconcat $ intersperse " " $ catMaybes links