我有一个字符串列表,我试图在下面的代码中添加一个字符串在列表的末尾,但我得到类型匹配错误:
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
还有其他办法吗?
答案 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]
此过程应指导您正确实施。仔细研究这些类型。我喜欢使用let
或where
来编写中间值的类型注释;这样,当表达式没有我期望的类型时,我会得到一个非常具体的类型错误。
答案 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"
之前的任何内容都不会更改。如果你想改变它,修改应该是微不足道的。