2012-01-07 48 views
1

我應該編寫帶有這樣的元素的列表,元素和返回位置的函數。像,泛化haskell函數

pos 2 [1, 2, 3, 2] -> [2, 4] 
pos 1 [1, 2, 3, 2] -> [1] 
pos 8 [1, 2, 3, 2] -> [] 

這就是我所做的。

--findFirstPosition :: Eq a => a -> [a] -> Maybe a 
findFirstPosition val xs = case f of 
    Nothing -> Nothing 
    Just (v, i) -> Just(i) 
    where f = (find (\ (v, i) -> val == v) (zip xs [1..])) 

--pos :: Eq a => a -> [a] -> [Int] 
pos _ [] = [] 
pos val xs = if (finded) 
    then concat[ 
      [fromJust res], 
      map (\a -> a + (fromJust res)) 
      (pos val (drop (fromJust res) xs))] 
    else [] 
    where 
    res = findFirstPosition val xs 
    finded = (isJust res) 

它的作品相當不錯。但是當我嘗試使用函數類型(如評論中所示)時發生錯誤

Could not deduce (a ~ Int) 
from the context (Eq a) 
    bound by the type signature for pos :: Eq a => a -> [a] -> [Int] 
    at \test.hs:(63,1)-(72,29) 
    `a' is a rigid type variable bound by 
     the type signature for pos :: Eq a => a -> [a] -> [Int] 
     at \test.hs:63:1 
Expected type: Maybe Int 
    Actual type: Maybe a 
In the first argument of `fromJust', namely `res' 
In the first argument of `drop', namely `(fromJust res)' 

我應該如何處理它?此外,任何額外的代碼審查意見,高度讚賞。

Upd 我應該使用find函數來實現它。

+0

注意:請使用空格縮進代碼,而不是製表符(至少在這裏,這裏的代碼格式化程序根本不喜歡標籤)。 – 2012-01-07 14:14:02

+1

改進的一些提示:讓我們考慮下面的表達式'concat [[fromJust res],map(\ a - > a +(fromJust res))(pos val(drop(fromJust res)xs))]''。該表達式具有'concat [[e1],e2]'的形式。檢查'concat'對於這種形式的參數的收益。此外,您可以爲「fromJust res」表達式定義一個短名稱,因爲它會多次出現。 – 2012-01-07 16:10:40

+0

@Jan Christiansen,謝謝我會做。 – 2012-01-07 17:34:45

回答

2

類型的findFirstPosition應該是

findFirstPosition :: Eq a => a -> [a] -> Maybe Int 

此功能的目的是要找到一個位置,或索引。所以返回類型應該包含適合於索引的東西,但與參數類型無關。

無關:你確定索引應該從1開始?通常是基於0的索引。

+0

是的。非常感謝。 – 2012-01-07 14:16:52

+0

這只是練習,所以它不會真正與基礎米)我會盡快接受這個答案。 – 2012-01-07 14:21:24

1

您可以使用列表理解更加合理地實現這一點。

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

我也改成了使用基於0指數與其他列表功能的一致性,但是如果你需要,你可以輕鬆地調整這基於1。

+0

你有沒有注意到這個問題被標記爲家庭作業? – is7s 2012-01-07 19:57:28

+0

謝謝,但實際上我應該在這個任務中使用'find'。對不起,我沒有提到這一點。 – 2012-01-07 20:12:14