2015-11-15 42 views
2

我們被要求在Haskell中自己編寫一個函數,當給定一個列表並且某個元素返回一個新列表時,它包含該列表中的那個元素。返回列表中某個元素的所有位置,但不包含遞歸,但帶有列表生成器

我已經嘗試了很長一段時間,但我目前仍然使用遞歸,任務說我們不應該使用遞歸。

allPositionsOf :: (Eq a) => a -> [a] -> [Int] 
allPositionsOf e es = [i | i <- [0 .. (length es - 1)], IsAtPos e es i] 
    where 
     isAtPos :: (Eq a) => a -> [a] -> Int -> Bool 
     isAtPos e (x:xs) 0 
          |x == e = True 
          |otherwise = False 
     isAtPos e (x:xs) i = findAtPosition xs e (i - 1) 

我知道有!和其他類似的功能,但它可能只是使用列表生成器,並保持簡單?

+0

你是什麼意思列表生成器? –

回答

5

我想你想要那樣的事嗎?

allPositionsOf :: Eq a => a -> [a] -> [Int] 
allPositionsOf b xs = [ i | (i,x) <- zip [0..] xs, x == b] 

λ> allPositionsOf 'b' "dfbhjbd" 
[2,5] 

你幾乎得到了它已經 - 這是唯一我只是增加了一個進一步

zip列表了[0,1,2,...]獲得並列indizes和元素邊,拿出一個(index,element)對(這裏(i,x)),過濾掉所有的地方x == b然後最後返回來自對的指標

+0

這太神奇了<3。但是,你不必寫'b(x:xs)'而不是'b xs'嗎? – Swift

+0

否 - 如果我這樣做,它不適用於空列表(因爲這種模式不匹配那些),我不需要在這裏解構列表(列表理解爲你做這個) – Carsten

+0

謝謝!這有很大幫助 – Swift

相關問題