Function 这个Haskell列表代码有什么问题?

Function 这个Haskell列表代码有什么问题?,function,haskell,functional-programming,Function,Haskell,Functional Programming,下面是我想做的一个例子 let b = ["this","is","a","test!"] "xx" ++ (b!!3) 这将给我“xxtest!” 基本上,如果列表包含任何带感叹号的字符串,则“xx”将添加到此特定字符串。我的问题是如何将其实现为正确的功能 现在我得到了这个 replaceElement [] = [] replaceElement (x:xs) = if '!' `elem` x then ["xx"] ++ x : replaceElement

下面是我想做的一个例子

let b = ["this","is","a","test!"]

"xx" ++ (b!!3)
这将给我“xxtest!”

基本上,如果列表包含任何带感叹号的字符串,则“xx”将添加到此特定字符串。我的问题是如何将其实现为正确的功能

现在我得到了这个

replaceElement [] = []
replaceElement (x:xs) =
      if '!' `elem` x
      then ["xx"] ++ x : replaceElement xs
      else x: replaceElement xs
但此函数只将“xx”作为元素添加到列表中,而不会添加到列表中的特定字符串中。如何使用“xx”+(b!!x),其中x是带感叹号的字符串的位置。

表达式

["xx"] ++ x : replaceElement xs
实际上被解析为

["xx"] ++ (x : replaceElement xs)
这正是您所描述的:在结果列表中插入
“xx”
。您想做的是:

("xx" ++ x) : replaceElement xs

关键是如何解析
[“xx”]++x:replaceElement xs
。这取决于操作员的固定性:

GHCi, version 7.10.2: http://www.haskell.org/ghc/  :? for help
Prelude> :info :
-- ...
infixr 5 :
Prelude> :i ++
(++) :: [a] -> [a] -> [a]   -- Defined in ‘GHC.Base’
infixr 5 ++
因此,
++
都是右关联运算符,具有相同的优先级。右关联意味着,
a:b:c
被解析为
a:(b:c)
,而不是
(a:b):c
(与左关联
infixl
的情况相同)。由于优先级相同,如果混合使用
++
,这仍然有效

["xx"] ++ x : replaceElement xs  ≡  ["xx"] ++ (x : replaceElement xs)
看,您只是在为整个结果预先添加
[“xx”]
,但单个元素从未与
“xx”
接触。要实现这一点,您需要将
“xx”
x
分组。因此,额外的括号是不必要的(事实上,这些括号可能会提示您:在额外的层中包装
“xs”
,意味着您不再按预期使用字符串级别,而是在字符串级别列表中)


当然,更好的选择是不进行任何手动递归:只需对列表的所有元素应用相同的操作;这就是地图的作用:

replaceElement = map $ \x -> if '!'`elem`x
                              then "xx"++x
                              else x

您还可以将
map
与以下辅助函数一起使用:

addxx :: [String] -> [String]
addxx = map checkBang
        where checkBang s | last s == '!' = "xx" ++ s
                          | otherwise     = s