我尝试使用折叠和追加进行字节串操作。请参阅下面的代码。
import qualified Data.ByteString.Char8 as C
selectSource :: [String] -> C.ByteString
selectSource xs = C.append (foldl addSource emptySource xs) (C.pack "<head>")
相应地定义了 addSource
和emptySource
。括号看起来有点难看,我想在selectSource
函数中删除它们
C.append $ foldl addSource emptySource xs $ C.pack "<head>"
但未能这样做并收到错误信息说
Couldn't match expected type ‘C.ByteString -> C.ByteString’
with actual type ‘C.ByteString’
The first argument of ($) takes one argument,
but its type ‘SourceByteString’ has none
In the second argument of ‘($)’, namely
‘foldl addSource emptySource [] $ C.pack "<head>"’
这有效
C.append (foldl addSource emptySource xs) $ C.pack "<head>"
但它仍然有最后一对括号。
答案 0 :(得分:9)
使用C.append
作为infix operator,您可以不加括号编写此内容。
selectSource :: [String] -> C.ByteString
selectSource xs = foldl addSource emptySource xs `C.append` C.pack "<head>"
由于ByteString
拥有mappend = append
个Monoid
个实例,您可以使用中缀import Data.Monoid
selectSource :: [String] -> C.ByteString
selectSource xs = foldl addSource emptySource xs <> C.pack "<head>"
运算符Monoid
更优雅地编写此实例。
"<head>"
如果启用<>
,您可以编写ByteString
之类的字符串文字,并将其用作ByteString
。 fromString
的{{1}}酌情pack
或packChars
(pack
Char8
为ByteString
。这可以摆脱一组括号,这将使你可以在没有任何括号的情况下编写selectSource
无点。
{-# LANGUAGE OverloadedStrings #-}
selectSource :: [String] -> C.ByteString
selectSource = flip C.append "<head>" . foldl addSource emptySource
如果您更喜欢flip
的操作符,则可以使用OverloadedStrings
来编写此点。这需要操作符周围的括号用于操作符部分语法。操作符部分括号不会打扰我,因为我从不嵌套它们。
{-# LANGUAGE OverloadedStrings #-}
import Data.Monoid
selectSource :: [String] -> C.ByteString
selectSource = (<> "<head>") . foldl addSource emptySource
使用无点定义,我们可以添加其他函数,如C.init
,而不会弄乱括号。
selectSource' :: [String] -> C.ByteString
selectSource' = flip C.append "<head>" . C.init . foldl addSource emptySource
selectSource' :: [String] -> C.ByteString
selectSource' = (<> "<head>") . C.init . foldl addSource emptySource