2012-01-07 16 views
1

このような要素でリスト、要素、およびリターンの位置をとる関数を記述する必要があります。同様に、Generalize 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)' 

どうすればいいですか?また、追加のコードレビューコメントも高く評価されます。

更新 find機能を使用して実装する必要があります。

+0

注:あなたのコードは、タブではなくスペースでインデントしてください(少なくともここでは、コードフォーマッタはタブがまったく好きではありません)。 –

+1

改善のためのヒント:次の式を考えてみましょう: 'concat [[fromJust res]、map(\ a-> a +(Just res))(pos val(drop from(Just res)xs))]'この式の形式は 'concat [[e1]、e2]'です。この形式の議論のために 'concat'がもたらすものを確認してください。さらに、式 'fromJust res'の短縮名を数回定義することもできます。 –

+0

@Jan Christiansen、ありがとう、私はそれをやるでしょう。 –

答えて

2

findFirstPositionのタイプは、この機能の目的は、位置、またはインデックスを見つけることである

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

であるべきです。そのため、戻り値の型は、索引付けに適したものをラップする必要がありますが、引数の型とは関係ありません。

関連しない:インデックスの開始が1で始まることを確認してください。通常は0ベースのインデックス作成です。

+0

うん。どうもありがとう。 –

+0

それはちょうど練習なので、それは本当にベースでは測らない)私は可能な限り早くこの答えを受け入れるだろう。 –

1

これは、リストの理解度を使用して、これをはるかに正確に実装できます。

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

私はまた、他のリスト機能との整合性のためのゼロベースのインデックスを使用するように変更しましたが、あなたがそれを必要とする場合は、簡単に1をベースにこれを調整することができます。

+0

質問に宿題とタグ付けされていることに気付きましたか? – is7s

+0

ありがとうございますが、実際にはこのタスクで 'find'を使うべきです。申し訳ありませんが、私はこれを言及しませんでした。 –