簡體   English   中英

如何在Haskell中的字符串列表中更改Char

[英]How to change a Char within a list of Strings in Haskell

我剛剛解決了一個問題,涉及使用字符串在某個位置更改某個Char:

changeStr :: Int -> Char -> String -> String
changeStr x char zs = take (x-1) zs ++ [char] ++ drop x zs

- 此函數接受int輸入,char和字符串,然后將int位置的字符串更改為指定的char。 它通過將字符串分成三部分來完成此操作,第一部分是指定位置之前的所有字符串,第二部分是指定位置,第三部分是指定位置之后的所有字符串。 然后將第二部分更改為指定的字符,並將所有內容連接在一起。

{-

Cw2013> changeStr 2 'i' "dog"
"dig"

-}

現在我基本上嘗試做類似於第一個問題的事情,但是通過使用函數changeStr作為輔助函數來使用字符串列表來完成它但我似乎感到困惑。 我似乎無法解決它。 以下是我在下面所做的事情:

changeRaw :: (Int,Int) -> Char ->  [String]-> [String]
changeRaw x y char zs = (take (y-1) zs) ++ (changeStr x char (head (take (y-1))) ++ (drop y zs)

對我做錯了什么建議?

你的問題的直接解決方案是你的(head (take (y-1)))應該是(head (drop (y-1) zs)) 稍微更好的替換是使用(zs !! (y-1)) ,因為(!!)是標准的(從零開始)Haskell列表索引操作。

另請注意,類型簽名(Int,Int) -> Char -> [String]-> [String]與您的函數模式changeRaw xy char zs不匹配。


但是,更多Haskellish解決方案會更簡單,更通用:

-- generalized helper function
mapElt :: Int -> (a -> a) -> [a] -> [a]
mapElt n f xs = take (n-1) xs ++ f (xs!!(n-1)) : drop n xs

-- generic replacement for changeStr
setElt :: Int -> a -> [a] -> [a]
setElt n e xs = mapElt n (const e) xs

-- generic replacement for changeRaw
setElt2 :: Int -> Int -> a -> [[a]] -> [[a]]
setElt2 x y e xss = mapElt y (setElt x e) xss

剩下的煩惱包括基於單一的索引,以及mapElt實現中仍然不優雅的索引機制。

[更新以反映編輯過的問題]

您還沒有針對changeStr一般解決方案。

你可以做得更優雅:

changeNLst :: Int -> a -> [a] -> [a]

你有很重的解決方案。

1)你可以用char : drop x zs替換[char] ++ drop x zs char : drop x zs

2)你可以使用splitAt :: Int -> [a] -> ([a], [a])

changeStr x char zs = before ++ (char : tail after)
    where (before, after) = splitAt (x-1) zs

中間位

changeStr x char (head (take (y-1))

缺少要在列表中沒有提到take從。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM