7

我想使用Haskell定義我自己的中綴運算符,它將兩個字符串連接在一起。但是,我想引入一個額外的子句,操作符將在兩個字符串中的重疊元素上進行連接。因此,一個例子是Concat兩個字符串在一起

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

我已經想出如何與琴絃返回的重疊部分:

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

但我不知道如何將在任何幫助?

+2

爲什麼不是第三個例子'「needucation」'? –

+1

爲什麼不是第一個例子「eagleeyes」? '檢查「鷹」「鷹」=「鷹」。 – dave4420

+0

是的抱歉,傢伙我意識到我在示例輸出中犯了一些錯誤。我糾正了 – Bobo

回答

8

你正在以一種錯誤的方式去做。

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

也就是說,你並不在乎重疊是什麼,你只是在乎你是否已經達到了它。


這是另一個沒有顯式遞歸的解決方案。

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

在這裏,我們去尋找的重疊,如您check,但不是保持重疊,我們得到的是xs重疊的部分。

+0

另一個使用Data.List.stripPrefix函數:xs +++++ ys = xs ++ head [suffix |只是後綴< - 地圖(翻蓋stripPrefix ys)(尾巴xs)] –

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

這會不會是儘可能快地提供,因爲它會隨着s以後進行兩次傳球,但我認爲這是更具可讀性,並具有直觀意義的其他版本。