[英]Haskell: Transposition on a list of strings
Haskell 的新手,到目前為止,該語言一直很有趣。 我希望得到一個好的提示而不是一個答案,因為我很享受 Haskell 的思維改變。
問題:我有一個字符串列表,我想轉置它們。
let x = ["hello", "world"]
會變成
["hw", "eo", "lr", "ll", "od"]
到目前為止,我所擁有的是:
transposeString :: [a] -> [a]
transposeString ([]:_) = []
transposeString x = (map head x) : transposeString (map tail x)
我肯定知道類型簽名有問題。 我的理性是
Let y = ["wow", "top"]
map head y
返回“wt”,所以在列表的其余部分遞歸它會起作用嗎?
提前感謝您的任何提示。
請注意,您不必提供類型簽名:Haskell 編譯器可以派生一個。 如果你把你的實現放在一個文件中:
transposeString ([]:_) = []
transposeString x = (map head x) : transposeString (map tail x)
並在ghci
使用:t
查詢類型,它返回:
*Main> :t transposeString
transposeString :: [[b]] -> [[b]]
這完全有道理:
[[b]]
是b
元素的列表; 和map head x
意味着元素x
必須是一個列表( [b]
因為我們執行的映射,我們不得不窩在列表中的一個額外的電平,使[[b]]
tail
。 據我所知,你的實現是正確的。 您可以通過說[b] ~ String
來專門化它,從而為String
s 添加類型簽名:
transposeString :: [String] -> [String]
transposeString ([]:_) = []
transposeString x = (map head x) : transposeString (map tail x)
這又是有道理的,因為String ~ [Char]
因此b ~ Char
。 但是專門化一個函數類型並沒有多大意義:你最好總是使用最通用的類型簽名。 在這種情況下[[b]] -> [[b]]
。
一個注意點。 您的tranposeString
類型簽名允許接受平面列表作為參數。 轉置[String]
有效,因為[String]
s 實際上只是[[Char]]
s,但是當您嘗試在[Int]
上調用transposeString
時會發生什么? 畢竟,類型簽名允許這樣做。
在旁注中,我問您,鑒於您當前的功能,如果您調用transposeString []
會發生什么?
記住String
是[Char]
"abc" == 'a' : 'b' : 'c' : []
從這里您可以使用列表的可遍歷性質:
transpose :: [[a]] -> [[a]]
transpose mat = getZipList $ sequenceA $ map ZipList mat
test' = transpose [[1,2,3],[4,5,6],[7,8,9]] -- == [[1,4,7],[2,5,8],[3,6,9]]
test'' = transpose ["abc", "deg", "klm"] -- == ["adk","bel","cgm"]
您還可以在 haskell doc https://hackage.haskell.org/package/base-4.12.0.0/docs/src/Data.OldList.html#transpose 中檢查transponse
默認實現
transpose :: [[a]] -> [[a]]
transpose [] = []
transpose ([] : xss) = transpose xss
transpose ((x:xs) : xss) = (x : [h | (h:_) <- xss]) : transpose (xs : [ t | (_:t) <- xss])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.