删除haskell语句中的括号

use*_*324 2 haskell functional-programming parentheses

我正在尝试使用折叠和追加字节串操作.请参阅下面的代码.

import qualified Data.ByteString.Char8 as C

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

addSource并相应emptySource地定义.用括号看起来有点难看,我想在selectSource函数中删除它们

C.append $ foldl addSource emptySource xs $ C.pack "<head>"
Run Code Online (Sandbox Code Playgroud)

但没有这样做,并得到一个错误消息说

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>"’
Run Code Online (Sandbox Code Playgroud)

这有效

C.append (foldl addSource emptySource xs) $ C.pack "<head>"
Run Code Online (Sandbox Code Playgroud)

但它仍然有最后一对括号.

Cir*_*dec 10

您可以使用不带括号写C.append缀操作符.

selectSource :: [String] -> C.ByteString
selectSource xs = foldl addSource emptySource xs `C.append` C.pack "<head>"
Run Code Online (Sandbox Code Playgroud)

由于ByteStrings有Monoid实例,mappend = append你可以使用中缀Monoid运算符更优雅地编写它<>.

import Data.Monoid

selectSource :: [String] -> C.ByteString
selectSource xs = foldl addSource emptySource xs <> C.pack "<head>"
Run Code Online (Sandbox Code Playgroud)

如果启用OverloadedStrings,则可以编写字符串文字"<head>",并将其用作ByteStrings.该ByteStringfromString要么是packpackChars为合适的(这是packChar8 ByteStringS).这可以摆脱一组括号,它可以让你在selectSource没有任何括号的情况下进行无点编写.

{-# LANGUAGE OverloadedStrings #-}

selectSource :: [String] -> C.ByteString
selectSource = flip C.append "<head>" . foldl addSource emptySource
Run Code Online (Sandbox Code Playgroud)

如果您更喜欢操作员,则flip可以使用操作员部分编写此点.这需要操作符周围的括号用于操作符部分语法.操作符部分括号不会打扰我,因为我从不嵌套它们.

{-# LANGUAGE OverloadedStrings #-}    
import Data.Monoid

selectSource :: [String] -> C.ByteString
selectSource = (<> "<head>") . foldl addSource emptySource
Run Code Online (Sandbox Code Playgroud)

无论是无点定义,我们都可以添加其他功能,例如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
Run Code Online (Sandbox Code Playgroud)