Допустим, у меня есть строка:
"abc7de7f77ghij7"
Я хочу разбить ее на подстроку, 7
в данном случае, и получить все разделения слева и справа:
[ ("abc", "de7f77ghij7")
, ("abc7de", "f77ghij7")
, ("abc7de7f", "7ghij7")
, ("abc7de7f7", "ghij7")
, ("abc7de7f77ghij", "")
]
Пример реализации:
{-# LANGUAGE OverloadedStrings #-}
module StrSplits where
import qualified Data.Text as T
splits :: T.Text -> T.Text -> [(T.Text, T.Text)]
splits d s =
let run a l r =
case T.breakOn d r of
(x, "") -> reverse a
(x, y) ->
let
rn = T.drop (T.length d) y
an = (T.append l x, rn) : a
ln = l `T.append` x `T.append` d
in run an ln rn
in run [] "" s
main = do
print $ splits "7" "abc7de7f77ghij7"
print $ splits "8" "abc7de7f77ghij7"
с ожидаемым результатом:
[("abc","de7f77ghij7"),("abc7de","f77ghij7"),("abc7de7f","7ghij7"),("abc7de7f7","ghij7"),("abc7de7f77ghij","")]
[]
Мне не очень нравится ручная рекурсия и let
/ case
/ let
вложение . Если мне кажется, что это не очень хорошо, то есть ли лучший способ написать это?
Есть ли в Haskell общий подход к решению подобных проблем, подобный тому, как может быть рекурсия заменены на fmap
и fold
s?