![](/img/trans.png)
[英]Haskell: Replace a subString in a String without Data.List package
[英]Substring in Haskell
我應該拆分一個字符串並返回在傳遞的字符之前發生的子字符串,但我們只是啟動Haskell,它對我來說就像中文。 我一直搞亂它,但沒有運氣。 這是我到目前為止所擁有的:
--spanString returns substring of string s before char c
spanString (c, [s])::(c, [s]) -> []
spanString (c, a:b) =
let (x, y) = spanString (c, b)
in
if a < c then (a:x,y)
else (x, a:y)
我搞砸了什么?
首先,你的類型簽名完全搞砸了。 它必須不存在或者是spanString :: <some type>
。 即使我們忽略了在雙冒號之前站立的(c, [s])
,其余的仍然是奇怪的。 人們可以把它讀作“將類型(c, [s])
的值取值為任何c和s的類型[]
值的函數”(c和s是類型變量)。 首先,Haskell中沒有類型[]
。 沒有元素類型的列表類型。 接下來,我們無法使用任何c
和s
。 我們必須能夠比較它們,對嗎?
實際上,讓我們暫時避免使用多態,並准確指定我們想要的類型。 我們想要一個字符和一個字符列表,由於某種原因打包成一個元組:( (Char, [Char])
。 請注意, Char
以大寫字母開頭,這意味着它不是類型變量,而是具體類型。 我們的結果類型怎么樣? 如果您信任問題描述,則需要返回一個字符列表( [Char]
),但如果查看代碼,它顯然會返回列表元組( ([Char], [Char])
)。 好的,也許第二個列表很有用,讓我們暫時離開:
spanString :: (Char, [Char]) -> ([Char], [Char])`
現在你的代碼編譯了。
但是,在運行時,它會發生異常崩潰: Non-exhaustive patterns in function spanString
。 這是因為當傳遞的列表為空時,您不處理這種情況。 如果你這樣做,可以添加一個等式
spanString (_, []) = ([], [])
,你的功能運行良好,但現在讓我們來看看它的功能。 事實證明,你有一個列表分區功能:它返回給定字符串的所有字符,小於c
作為元組的第一個元素,所有其他字符作為第二個元素。 對我來說似乎是一個錯誤(你已經實現了一個完全不同的功能!)。
呃,非常多。
首先,您的類型聲明是錯誤的。 Haskell對類型使用大寫名稱,並且它不像大多數語言那樣傳遞括號中的參數。 我們寫
y = sin x
代替
y = sin (x)
你可能想要這樣的東西
spanString :: Char -> String -> String
你對spanString的定義在語法上是正確的,但仍然是錯誤的。 這樣考慮一下:如果第一個字符不匹配,那么你想要spanString其余的字符串然后返回結果,前面加上第一個字符。 如果第一個字符匹配,那么您想要返回“”。
你的類型定義是錯誤的。
spanString :: Char-> String-> String
spanString _ [] = []
spanString c (x:xs) | c==x = []
| otherwise = x:spanString c xs
僅供參考,像這樣的實用程序函數幾乎總是可以在Prelude或標准庫中找到。 在這種情況下, takeWhile
將幫助:
spanString :: (Char, String) -> String
spanString (c, s) = takeWhile (/= c) s
(即,在不等於c
繼續拍攝角色)。
在元組中傳遞參數有點奇怪,但如果這就是所需要的那么就是它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.