0

次の機能があるとします。

--count number of an item in a list
count :: (Eq a) => a -> [a] -> Double
count x []     = 0.0
count x (y:ys) = (is x y) + count x ys

--returns 1 if items match, else 0
is :: (Eq a) => a -> a -> Double
is x y
    | x == y    = 1.0
    | otherwise = 0.0

--compute length of the list
len :: [a] -> Double
len []     = 0.0
len [x]    = 1.0
len (x:xs) = 1.0 + len xs

このメソッドを使用して、正規化されたカウントを生成する関数を生成したいと思います。

--generates frequency of item in list
ncount :: (Eq a) => a -> [a] -> Double
ncount x [] = 0.0
ncount x y  = norm * (count x y)
    where
    norm = 1.0 / len y

この場合の署名がどのように処理されるべきかを知りたいだけです。count署名(Eq a) => a -> [a] -> Doubleがありますが、それも必要ncountですか? 一方では、を呼び出すときにaが含まれていない場合、後続の への呼び出しは失敗します。一方、等しいかどうかをテストすることはありません。Eqncountcountncount

申し訳ありませんが、省略しislen.:w

4

1 に答える 1

2

一般的に言えば、各関数が受け入れることができる最も多様な (つまり、最も包括的な) 型シグネチャを各関数に与えるのが最善です。関数の別の用途が別の場所で見つかる可能性は常にあります。

次のことが非常に役に立ちます。

  1. 型シグネチャなしで関数をコーディングします。
  2. 必要な型シグネチャ決定します。
  3. コマンドを使用して、型シグネチャがどうあるべきかを GHCi に尋ね:tます。
  4. (2) と (3) を比較してください。

これにより、2 つのことが達成されます。まず、GHCi は、私が最初に書いた関数よりも広い型シグネチャを提案するかもしれません。通常は、より広いタイプ シグネチャの方が優れています。次に、関数が意図したとおりに動作していることを確認します。これにより、実装のバグが浮き彫りになることがあります。

もちろん、より狭い型シグネチャがより適切な場合もあります。計算はさまざまな型に対して実行できますが、一部の型に対してのみ「意味がある」場合があります。しかし、実際には、そのようなケースはめったにありません。Satvik が指摘したように、もう 1 つの理由はパフォーマンスの問題です。

于 2013-08-26T13:59:20.627 に答える