1

Haskell の型に関する初心者向けの質問があります。次のような関数があります。

f i xs = (sort xs) !! i

f0 xs = f 0 xsxs を明示的に使用せずに関数を定義するにはどうすればよいですか? 取ってるだけ

f0 = f 0

動作しません...

ghci は次のような型を示してくれます:
f :: Ord a => Int -> [a] -> a
f0 :: [()] -> ()
しかし、":tf 0" はf 0 :: Ord a => [a] -> a.

何故ですか?f0 でこの型を取得するのはなぜですか? 「f0」の型と「f 0」の型に違いがあるのはなぜですか?

提案をお寄せいただきありがとうございます

4

1 に答える 1

5

それはあなたの特定の定義とは何の関係もありません: 標準の実装で (当然のことですが!) それを行うと、同じことが起こります。

Prelude> let f0 = 最大
Prelude> :t f0
f0 :: [()] -> ()

f何はともあれ、まずはサインをお願いします。

f :: Ord a => Int -> [a] -> a

同様にそれを行うとf0、すべてうまくいきます:

f0 :: Ord a => [a] -> a

問題は、なぜ ghci がそのようなばかげた署名を推測するのかということです。恐怖の単形性制限のせいだ。つまり、何かを「定数(-applicative form)として」、つまり単純な方程式として定義するときはいつでも、

c = any odd stuff

aその場合、コンパイラは自動的にポリモーフィック シグネチャ (型変数を含む)を与えることを拒否します。代わりに、デフォルトで「最も簡単に使用できる」タイプになりOrdますが、残念ながら、これは制約にはまったく役に立たない().

モノモーフィズムの制限をオフにすると、署名がなくても機能します。

Prelude> :set -XNoMonomorphismRestriction
Prelude> let f0 = 最大
Prelude> :t f0
f0 :: Ord a => [a] -> a

しかし正直なところ、最上位レベルでは常に手動署名を使用する必要があります。

于 2014-04-16T20:29:49.947 に答える