2

I have a list of Strings and I am trying to add a String at the end of the list in the following code but I am getting type matching errors:

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

What the code actually does is that the function eleminateImpl takes a first order logic expression, for example: "eliminateImpl ["Q(y)","Impl","P(x)"] []" and it should remove the implication and modify the expression so that the output is: "eliminateImpl ["Not", "Q(y)"," Or ","P(x)"]

I tried r++p and r:p but both are not working. This is the error:

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

Is there another way to do it?

6
  • What should the list of strings look like afterwards? Commented Nov 23, 2014 at 17:27
  • Can you explain exactly what you wan't to do? I can't seem to make sense of what you have written. Commented Nov 23, 2014 at 17:30
  • @SebastianRedl The function should get a first order logic expression, for example: "eliminateImpl ["Q(y)","Impl","P(x)"] []" and the function should remove the implication and modify the expression so that the output is: "eliminateImpl ["Not", "Q(y)"," Or ","P(x)"]" Commented Nov 23, 2014 at 17:30
  • 1
    you want to replace ++ with : throughout this line Commented Nov 23, 2014 at 17:32
  • Should it replace all occurrences of "impl" or only one? Commented Nov 23, 2014 at 17:46

2 Answers 2

1

If I understood you correctly, this seems to be close to what you want:

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

If I have misunderstood, please comment and I will change my answer.

To replace only one implication:

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

These functions should go through the list of Strings until they find the first "impl". Nothing before the "impl" will be changed. If you want to change this the modifications should be trivial.

Sign up to request clarification or add additional context in comments.

3 Comments

Yes the logic is correct. There were only minor syntax problems with it that I fixed and now it works perfectly. I am confused though why after fixing the appending of the variables in my own code I got a stackOverflow problem but this one does not.
Wouldn't it be easier to replace the two terminating cases with a single EliminateImpl xs = xs case after the special case?
@SebastianRedl - Probably, I just don't think in that order, probably because of the way recursion works in imperative languages.
1

Type annotations:

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]

This process should guide you to a correct implementation. Work through the types carefully. I like to use let or where to write in type annotations for intermediate values; that way I'll get a really specific type error when an expression doesn't have the type I expect.

2 Comments

I fixed it but now I got a "ERROR - C stack overflow". Any ideas why?
Also r is not a String, it is an [String] as well. But somehow this worked fine. Except for the Stackoverflow error.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.