删除 haskell 语句中的括号

Remove parenthesis in a haskell statement

我正在尝试使用折叠和追加进行字节串操作。请看下面的代码。

import qualified Data.ByteString.Char8 as C

selectSource :: [String] -> C.ByteString
selectSource xs = C.append (foldl addSource emptySource xs) (C.pack "<head>")

addSourceemptySource 是相应定义的。括号看起来有点难看,我想在 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>"

但它还有最后一对括号。

您可以使用 C.append 作为 infix operator.

来编写不带括号的代码
selectSource :: [String] -> C.ByteString
selectSource xs = foldl addSource emptySource xs `C.append` C.pack "<head>"

因为 ByteStringMonoid instances with mappend = append you can write this more elegantly with the infix Monoid operator <>.

import Data.Monoid

selectSource :: [String] -> C.ByteString
selectSource xs = foldl addSource emptySource xs <> C.pack "<head>"

如果启用 OverloadedStrings,您可以编写 "<head>" 之类的字符串文字并将它们用作 ByteStringByteStringfromString 可以是 packpackChars(对于 Char8 ByteString 来说是 pack)。这可以去掉一组括号,这样你就可以在没有任何括号的情况下写 selectSource 点。

{-# LANGUAGE OverloadedStrings #-}

selectSource :: [String] -> C.ByteString
selectSource = flip C.append "<head>" . foldl addSource emptySource

如果您更喜欢运算符而不是 flip,则可以使用 operator section 来编写这个无意义的运算符。这需要在运算符部分语法的运算符周围加上括号。运算符部分括号不要打扰我,因为我从不嵌套它们。

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