2012-02-23 16 views
5

私はF#関数を持っている:F#値の制限

let removeEven (listToGoUnder : _ list) = 
    let rec listRec list x = 
     match list with 
     | [] -> [] 
     | head::tail when (x%2 = 0) -> head :: listRec (tail) (x+1) 
     | head::tail -> listRec (tail) (x+1) 

    listRec listToGoUnder 0 

それはリストの中にもインデックスですべての要素を削除します。 私はリストをいくつかのimputを与えると動作します。removeEven ['1';'2';'3']のように私は['1';'3']を取得します。しかし、パラメータとして空のリストを挿入すると、このエラーが発生します。

stdin(78,1): error FS0030: Value restriction. The value 'it' has been inferred to have generic type

val it : '_a list Either define 'it' as a simple data term, make it a function with explicit arguments or, if you do not intend for it to be generic, add a type annotation.

助けてください、誰か?

答えて

7

空のリスト([])は非常に特殊です。任意のタイプのリストにすることができます。したがって、コンパイラは、[]の特定の型がないと不満を表明します。 @kvbにより示唆されるように

let results = removeEven ([]: int list) 

以上の慣用型注釈:引数に型注釈を追加すると、問題を解決するのに役立ちます

let results: int list = removeEven [] 

これが問題を超えて、おそらくですが、あなたの関数はすべきインデックスは0から始まることが多く、関数は奇数インデックスを持つすべての要素を削除するため、removeOddという名前になります。あなたは、リストの最初の2つの要素の上にパターンマッチングを使用するのではなくインデックスをチェックするためのカウンタxを続ける場合はさらに、物事ははるかに明確である:あなたが代わりresults` `に直接注釈を追加することができます

let rec removeOdd = function 
    | [] -> [] 
    | [x] -> [x] 
    | x::_::xs -> x::removeOdd xs 
+0

注意、それはより慣用的かもしれない。 – kvb

+0

引数が '[]'の場合、提案されたremoveOdd関数は失敗します。 私はこれを一般的な方法で解決しようとしていますが、「エラーFS0030:値の制限」なしで '[]'のケースを処理することはできません。 このような機能を本当に汎用的にすることは可能ですか? – TurboHz