2015-07-19 21 views
4

我試圖改寫:不能穿插「」和unwords被用作替換對方的替代品嗎?

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 

我不是最大的哈斯克爾還,但我認爲intersperse " "unwords哪裏只是在互相替換?

編輯:最後,我想找出一種方法來使用unwords ...弄清楚爲什麼它給我的錯誤,我怎麼能解決它是我們的目標! =)

+3

它們是不同的類型。 'mconcat。散佈「」一起是「unwords」。 –

+0

@ n.m。或者只是'concat。 Intersperse「」' – AJFarmar

回答

8

unwords :: [String] -> String功能僅適用於的String小號名單。你有什麼是MarkupM()類型值的列表。

intersperse :: a -> [a] -> [a]工作的原因是它可以工作在任何類型的列表上。使用OverloadedStrings編譯指示," "值的類型爲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。

2

如果您使用LANGUAGE OverloadedStrings,您將擁有什麼功能。

否則,請使用intersperse (text " ")而不是intersperse " "

例如爲:

{-# 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 
+0

我正在使用'{ - #LANGUAGE OverloadedStrings# - }',我仍然無法使用unwords。我的意思是,它使用'intersperse「''工作正常,但我覺得必須有一種方法來寫它,否則。 – Berkson