在Idris中,字符串是基元,而不是Haskell中的列表。因此,我希望会有某种基本的replace : (needle : String) -> (replacement : String) -> (haystack : String) -> String
函数la Data.Text.replace
。我找不到这个。但是我想,也许我可以在Data.List.Utils.replace
中找到一些replace : Eq a => (needle : List a) -> (replacement : List a) -> (haystack : List a) -> List a
函数,因为Idris确实提供了unpack : String -> List Char
和pack : Foldable t => t Char -> String
。但是,我也找不到Idris中定义的列表的replace
。我已经在文档和GitHub repo中搜索了几样东西,并在REPL中用:browse
进行了查找,但是都算不上运气。当然,良好的旧Idris的replace
函数用于处理类型,而不是用于字符串……(这使我很高兴,但不能解决我的问题)。
最后,我将Data.List.Utils.replace
从Haskell移植了过来,但是我不知道它的性能,更糟糕的是,它还不是全部。而且,对于我通常认为是原始操作的代码,它需要大量的代码(假设字符串是原始数据)。
spanList : (List a -> Bool) -> List a -> (List a, List a)
spanList _ [] = ([],[])
spanList func list@(x::xs) =
if func list
then
let (ys,zs) = spanList func xs
in (x::ys,zs)
else ([],list)
breakList : (List a -> Bool) -> List a -> (List a, List a)
breakList func = spanList (not . func)
partial
split : Eq a => List a -> List a -> List (List a)
split _ [] = []
split delim str =
let (firstline, remainder) = breakList (isPrefixOf delim) str in
firstline :: case remainder of
[] => []
x => if x == delim
then [] :: []
else split delim (drop (length delim) x)
partial
strReplace : String -> String -> String -> String
strReplace needle replacement =
pack . intercalate (unpack replacement) . split (unpack needle) . unpack
我将重塑它,直到获得全部,因为我看不出为什么不能将其全部确定,但是与此同时,我还缺少什么?人们真的在Idris中进行了很少的字符串操作以至于根本无法使用它吗?我假设contrib
中至少会有一些东西。您如何在Idris中进行字符串替换?
答案 0 :(得分:2)
对于以后找到这个并想要实现的任何人,这是我目前拥有的:
module ListExt
%default total
%access public export
splitOnL' : Eq a => (delim : List a) -> {auto dprf : NonEmpty delim }
-> (matching : List a) -> {auto mprf : NonEmpty matching}
-> List a -> (List a, List (List a))
splitOnL' _ _ [] = ([], [])
splitOnL' delim m@(_::m') list@(x::xs) =
if isPrefixOf m list
then
case m' of
[] => ([], uncurry (::) $ splitOnL' delim delim xs)
(m_ :: ms) => splitOnL' delim (m_ :: ms) xs
else
let (l, ls) = splitOnL' delim delim xs in
(x :: l, ls)
splitOnL : Eq a => (delim : List a) -> {auto dprf : NonEmpty delim}
-> List a -> List (List a)
splitOnL delim [] = []
splitOnL delim list@(_::_) = uncurry (::) $ splitOnL' delim delim list
substitute : Eq a => List a -> List a -> List a -> List a
substitute [] replacement = id
substitute (n :: ns) replacement = intercalate replacement . splitOnL (n :: ns)
strReplace : String -> String -> String -> String
strReplace needle replacement = pack . substitute (unpack needle) (unpack replacement) . unpack
我可能会尝试将PR提交回去,以将其包含在Idris的基础库中。 警告:我没有进行过性能测试,甚至没有严格测试过;我已经在大约十几个案例上运行了它,这似乎是正确的。如果仅分析算法,就会发现它效率不如您期望的那样。到目前为止,我还没有成功实现更高效的版本,同时又保持了总体水平。