Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Concat two strings together

I want to define my own infix operator using Haskell that concats two strings together. However, I want to throw in an extra clause where the operator will concat over the overlapping elements in both strings. So an example would be

"eagle" myinfix "eagleeyes" = "eagleeyes"
"water" myinfix "book" = "waterbook"
"need" myinfix "education" = "needucation"

I already figured out how to return the overlapping portions in the strings with:

check x y = head $ filter (`isPrefixOf` y) (tails x)

But I don't know how to incorporate that in. Any help?

like image 364
Bobo Avatar asked Oct 08 '12 08:10

Bobo


2 Answers

You're going about it in slightly the wrong way.

(+++) :: Eq a => [a] -> [a] -> [a]
xs     +++ ys | xs `isPrefixOf` ys = ys
(x:xs) +++ ys                      = x : (xs +++ ys)

That is, you don't really care what the overlap is, you just care whether you have reached it.


Here's another solution without the explicit recursion.

(++++) :: Eq a => [a] -> [a] -> [a]
xs ++++ ys = prefix ++ ys
  where (prefix, _) : _ = filter (\(_, overlap) -> overlap `isPrefixOf` ys) $ zip (inits xs) (tails xs)

Here we go about finding the overlap, as in your check, but instead of keeping the overlap, we yield the portion of xs that doesn't overlap.

like image 119
dave4420 Avatar answered Oct 21 '22 00:10

dave4420


overlapConcat :: (Eq a) => [a] -> [a] -> [a]
overlapConcat s t = s ++ drop (length $ check s t) t

This won't be as fast as the other versions provided since it will perform two passes over s, but I think it is more readable, and makes intuitive sense.

like image 43
bisserlis Avatar answered Oct 21 '22 00:10

bisserlis