2014-03-07 88 views
0

我最近學習了Haskell,在第一次課程中,我被告知要先學習如何操作列表。我知道如何挑選一個列表元素從是這樣的使用位置返回一個列表元素

myList = [7, 3, 6, 15, 8] 
    myList !! 3 

現在的位置,我想知道是否有可能從列表中挑選的最後一個元素開始的位置,就像我一直在做什麼在Python中使用該

pythonlist = [7, 3, 6, 15, 8] 
    pythonlist[-2] 

回答

1

首先,如果你發現自己被指數accesing列表(你不應該經常這樣做,無論如何,這是低效的和醜陋的:喜歡功能的工具,如褶皺,map,和單子實例),那麼你應該更好地切換到一些數組數據類型,例如Vector

但果然是可能通過索引來訪問列表,也從背後:

(!!<) :: [a] -> Int -> a 
l !!< i = l !! i' 
where i' = length l - i - 1 

我希望這是明顯不夠是如何工作的。它比普通訪問效率更低,因爲length會遍歷整個列表,但是在那裏。

+0

這也是正確的(!! <) :: [a] ->詮釋 - >一 升!

+0

是的,也許甚至是有點更好 – leftaroundabout

+0

我只是爲了多樣性而添加它:) –

0

在某些情況下,是的。你可以簡單地重新定義(!!)到:

xs !! i | i >= 0 = xs Data.List.!! i 
     | i < 0 = let n = length xs 
        in xs Data.List.!! (n+i) 

然而,這是不是真的在Haskell一個偉大的想法,由於懶惰。上面的解決方案適用於有限的列表,這是您在Python中討論的內容。想想無限清單上會發生什麼,但是:[1..] !! (-2)。我們首先評估length [1..],它永不終止!問題是你無法從無限列表的末尾索引。

+0

爲了使這至少有點一致,我寧願定義一個新的操作符,例如''xs !!!我= xs! (我'mod'長度列表)'',以允許負指數作爲「通過環繞安全索引」的特例。但實際上我寧願不要有這種可能性,這是國際海事組織比混亂更有幫助。 – leftaroundabout

1

你可以這樣做:

(!!<) :: [a] -> Int -> a 
l !!< i = (reverse l) !! i 

但它意味着你不能使用負數,只有積極的指標,但它看起來從列表的末尾。

或者,如果你真的想使用底片:

(!!<) :: [a] -> Int -> a 
l !!< i = if i < 0 then l !! (length l + i) else l !! i 
相關問題