簡體   English   中英

Haskell:字符串列表上的換位

[英]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]]

這完全有道理:

  1. 你轉置一個矩陣,它是一個列表列表。 [[b]]b元素的列表;
  2. 你可以從自己的實施方法推導: 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.

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