7

Voglio definire il mio operatore infisso utilizzando Haskell che concatena due stringhe insieme. Tuttavia, voglio inserire una clausola aggiuntiva in cui l'operatore concatena gli elementi sovrapposti in entrambe le stringhe. Quindi, un esempio potrebbe essereConcat due stringhe insieme

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

ho già capito come restituire le parti sovrapposte nelle stringhe con:

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

Ma io non so come incorporare che in ogni aiuto.?

+2

Perché il terzo esempio non è "needucation"? –

+1

E perché il primo esempio non è "" eagleeyes "? 'check" eagle "" eagleeyes "=" eagle "'. – dave4420

+0

sì, mi dispiace ragazzi ho capito di aver fatto degli errori nelle uscite di esempio. Ho corretto quello – Bobo

risposta

8

Stai andando all'incirca nel modo sbagliato.

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

Cioè, non ti interessa davvero quale sia la sovrapposizione, ti interessa solo che tu l'abbia raggiunta.


Ecco un'altra soluzione senza la ricorsione esplicita.

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

Qui si fa a trovare la sovrapposizione, come nel vostro check, ma invece di mantenere la sovrapposizione, cediamo la parte di xs che non sovrapposizione.

+0

Un altro usando la funzione Data.List.stripPrefix: xs +++++ ys = xs ++ testa [suffisso | Solo suffisso <- map (flip stripPrefix ys) (code xs)] –

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

Questo non sarà veloce come le altre versioni fornite in quanto esso deve svolgere due passaggi sopra s, ma penso che sia più leggibile, e ha un senso intuitivo.