Haskell - 如何将String连接到字符串列表

时间:2014-11-23 17:22:34

标签: string list haskell ghci

我有一个字符串列表,我试图在下面的代码中添加一个字符串在列表的末尾,但我得到类型匹配错误:

eliminateImpl :: [String] -> String -> [String]
eliminateImpl [] _ = []
eliminateImpl (p:ps) r = if (contains (p:ps) "Impl")
                         then if (p == "Impl" )
                              then "Not " ++r++" Or "++ps -- TRYING TO CONCATENATE HERE
                              else let r = r++p
                                   in eliminateImpl ps r
                          else (p:ps)

contains :: [String] -> String -> Bool
contains [_] [] = True
contains [] _ = False
contains (p:ps) c = if p == c
                    then True
                    else contains ps c

代码实际上做的是函数eleminateImpl采用一阶逻辑表达式,例如:“eliminateImpl [”Q(y)“,”Impl“,”P(x)“] []”它应该删除暗示并修改表达式,使输出为:“eliminateImpl [”Not“,”Q(y)“,”Or“,”P(x)“]

我试过r ++ p和r:p但两者都不起作用。这是错误:

  

无法将'Char'类型与'[Char]'

匹配
Expected type: [String]

  Actual type: [Char]

In the first argument of ‘(++)’, namely ‘"Not "’

In the expression: "Not " ++ r ++ " Or " ++ ps

In the expression:

  if (p == "Impl") then

      "Not " ++ r ++ " Or " ++ ps

  else

      let r = r ++ p in eliminateImpl ps r

还有其他办法吗?

2 个答案:

答案 0 :(得分:1)

输入注释:

r :: String
p :: String
ps :: [String]
-- We need to produce a [String], not a String

(++) :: [a] -> [a] -> [a]
(++) :: String -> String -> String -- Because String = [Char]

(:) :: a -> [a] -> [a]

"Not " ++ r ++ " Or " :: String
("Not " ++ r ++ " Or ") : ps :: [String]

此过程应指导您正确实施。仔细研究这些类型。我喜欢使用letwhere来编写中间值的类型注释;这样,当表达式没有我期望的类型时,我会得到一个非常具体的类型错误。

答案 1 :(得分:1)

如果我理解正确,这似乎接近你想要的:

EliminateImpl :: [String] -> [String]
EliminateImpl [] = []
EliminateImpl [x] = [x]
EliminateImpl (pred:impl:rest) str
    | impl == "impl" = ("Not" : pred : "Or" : (EliminateImpl rest))
    | otherwise = (pred : (EliminateImpl (impl : rest)))

如果我误解了,请发表评论,我会改变我的答案。

只替换一个含义:

EliminateImpl :: [String] -> [String]
EliminateImpl [] = []
EliminateImpl [x] = [x]
EliminateImpl (pred:impl:rest) str
    | impl == "impl" = ("Not" : pred : "Or" : rest)
    | otherwise = (pred : (EliminateImpl (impl : rest)))

这些函数应该遍历字符串列表,直到找到第一个"impl""impl"之前的任何内容都不会更改。如果你想改变它,修改应该是微不足道的。