2014-11-23 62 views
2

我有一个字符串列表,我想在下面的代码列表的末尾添加一个字符串,但我收到类型匹配错误列表:哈斯克尔 - 如何将字符串到字符串

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采用一阶逻辑表达式,例如:“eliminationImpl [”Q(y)“,”Impl“,”P(x)“] []”和它应去除含义并修改表达式,以便输出为:“exceptImpl [”Not“,”Q(y)“,”Or“,”P(x)“]

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

Couldn't match type ‘Char’ with ‘[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

之后的字符串列表应该是什么样的? – 2014-11-23 17:27:17

+0

你能解释一下你想做什么吗?我似乎无法理解你写的内容。 – user2008934 2014-11-23 17:30:24

+0

@SebastianRedl函数应该得到一个一阶逻辑表达式,例如:“eliminateImpl [”Q(y)“,”Impl“,”P(x)“] []”,函数应该删除蕴含并修改表达式,以便输出为:“exceptImpl [”Not“,”Q(y)“,”Or“,”P(x)“]” – SalmaFG 2014-11-23 17:30:39

回答

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"之前没有任何更改。如果你想改变这种修改应该是微不足道的。

+0

是的逻辑是正确的。我只修复了一些小的语法问题,现在它完美地工作。我很困惑,但为什么在我自己的代码中修改变量的附加后,我得到了一个stackoverflow问题,但这不是。 – SalmaFG 2014-11-23 18:05:24

+0

在特殊情况之后用单个'EliminateImpl xs = xs'情况替换两个终止情况不是更容易吗? – 2014-11-23 22:33:48

+0

@SebastianRedl - 可能,我只是不按顺序思考,可能是因为递归在命令式语言中的作用。 – user2008934 2014-11-23 22:40:06

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来写入中间值的类型注释;这样,当表达式不具有我期望的类型时,我会得到一个真正特定的类型错误。

+0

我修正了它,但现在我得到了一个“错误 - C堆栈溢出”。任何想法为什么? – SalmaFG 2014-11-23 17:45:59

+0

另外r不是一个字符串,它也是一个[String]。但不知何故,这工作得很好。除了Stackoverflow错误。 – SalmaFG 2014-11-23 17:53:59