スコーレムって何?
質問
えーっ! GHCiが私のコードの中にSkolemsを発見しました!
...
Couldn't match type `k0' with `b'
because type variable `b' would escape its scope
This (rigid, skolem) type variable is bound by
the type signature for
groupBy :: Ord b => (a -> b) -> Set a -> Set (b, [a])
The following variables have types that mention k0
...
彼らは何なのか? 彼らは私のプログラムに何を望んでいるのか? そして、なぜ彼らは逃げ出そうとしているのか(恩知らずの小悪党どもめ)?
どのように解決するのですか?
そもそも、あるコンテキストにおける "rigid" 型変数とは、そのコンテキスト外の量詞で束縛された型変数を意味し、したがって他の型変数と統一することはできない。
これはラムダによって束縛される変数と非常によく似ています。ラムダが与えられると
(\x -> ... )
が与えられたら、もちろん外側から好きな値に適用することができます。
x
の値はある特定の値であるべきだと決めることはできません。の値を選択することは
x
に対して値を選ぶことは、かなり馬鹿げているように聞こえますが、これが "can't match blah blah, rigid type variable, blah blah" についてのエラーが意味するところです。
なお、明示的な
forall
の量詞を使わなくても、トップレベルの型署名には暗黙のうちに
forall
を持ちます。
もちろん、これはあなたが得たエラーではありません。エスケープされた型変数が意味するものはもっと愚かなもので、ラムダの
(\x -> ...)
の特定の値を使おうとしているようなものだ。
x
外
というように、ラムダを引数に適用するのとは別に、ラムダを使うことができます。いや、ラムダを何かに適用してその結果値を使うのではなく、実際に
変数自体
を定義されたスコープ外で実際に使うということです。
ラムダの例のように明らかに不合理に見えることなく)型でこのようなことが起こるのは、quot;型変数" の2つの概念が出回っているからです。単一化の際、未確定の型を表すquot;変数"があり、これは型推論によって他の変数と識別される。一方、上記の定量化された型変数があり、これは可能な型に及ぶものとして明確に識別されます。
ラムダ式の型について考えてみましょう。
(\x -> x)
. 完全に未決定の型から出発して
a
であることから、引数を1つ取り、それを絞って
a -> b
に、そして、引数と同じ型のものを返す必要があることがわかるので、さらに絞って
a -> a
. しかし、これでどんな型に対しても
a
が欲しいかもしれないので、量詞を与えます。
(forall a. a -> a)
.
つまり、エスケープされた型変数は、GHCが未確定の型に統一されるべきだと推測する量詞によって束縛された型があるときに発生します。 の外側 の外にある未決定の型に統一されるべきだとGHCが推測しているときです。
どうやら、ここで実際に "skolem type variable" という用語を説明するのを忘れていたようです、へぇ。コメントで述べたように、私たちの場合、それは本質的に "rigid type variable" と同義なので、上記はまだアイデアを説明しています。
この用語がどこから来たのか完全にはわかりませんが、おそらくは スコーレム正規形 を表現し 実存的 を表現することができます。スコレム(またはリジッド)型変数とは、ある範囲内で、多相型の一部である、実存的データ型から来るなど、何らかの理由で未知の、しかし特定の型を持つものを指します。
関連
-
[解決済み] エラー haskell: スコープ内にありません。どういう意味ですか?
-
[解決済み] C#のStringとstringの違いは何ですか?
-
[解決済み] C++のPOD型とは何ですか?
-
[解決済み] Pythonの旧スタイルのクラスと新スタイルのクラスの違いは何ですか?
-
[解決済み] Haskellは実世界で何に使われているのか?[クローズド]
-
[解決済み】type()とisinstance()の違いは何ですか?)
-
[解決済み] GHCはなぜこんなに大きいのか/大きいのか?
-
[解決済み】Haskell/GHCの`forall`キーワードは何をするのですか?
-
[解決済み] Haskellの初心者向けガイド?[終了しました]
-
[解決済み] Haskellの派生はどのように行われるのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] haskellにおけるdrop関数 - リスト内包を用いた実装
-
[解決済み] ghciで関数を複数行に渡って定義するには?
-
[解決済み] レコードの単一フィールドを割り当て、残りのフィールドはコピーするための省略記法?
-
[解決済み] <*>は何と呼ばれ、何をするのですか?[クローズド]
-
[解決済み] Real World Haskellのどの部分が今となっては時代遅れ、あるいはバッドプラクティスと考えられているのでしょうか?
-
[解決済み] Haskellの合成演算子(.)とF#のパイプ転送演算子(|>)の比較
-
[解決済み] 関数型プログラミングを実世界で使うには?[クローズド]
-
[解決済み] なぜStringを型クラスのインスタンスにできないのですか?
-
[解決済み] なぜこのHaskellコードは "infinite type "エラーを発生させるのでしょうか?
-
[解決済み] モナドが合成の下では閉じていないことを示す具体例(証明付き)?