[解決済み] 型チェッカーは非常に間違った型置換を許可しているが、プログラムはまだコンパイルできる
質問
私のプログラムの問題 (半径が等しい 2 つの円が異なる大きさで描画される) をデバッグしようとしているときに、Gloss
*
を使用して、半径が等しい 2 つの円が異なるサイズで描画される) をデバッグしようとしているときに、奇妙な状況に出くわしました。オブジェクトを処理するファイルで、次のように
Player
:
type Coord = (Float,Float)
data Obj = Player { oPos :: Coord, oDims :: Coord }
で、Objects.hsをインポートした私のメインファイルでは、次のような定義をしています。
startPlayer :: Obj
startPlayer = Player (0,0) 10
これは、私がプレーヤーのフィールドを追加したり変更したりしたために、更新を忘れてしまったために起こりました。
startPlayer
を更新し忘れたことが原因です (その寸法は半径を表す単一の数値で決定されましたが、私はそれを
Coord
に変更しました(プレイヤーオブジェクトを非円形にする場合に備えて、(width,height)を表すために)。
驚くべきことは、2番目のフィールドが間違った型であるにもかかわらず、上記のコードはコンパイルされ、実行されるということです。
私は最初、ファイルの異なるバージョンを開いていたのかもしれないと思いましたが、どのファイルへの変更もコンパイルされたプログラムに反映されました。
次に私は、もしかしたら
startPlayer
は何らかの理由で使われていないのではと思いました。コメントアウトすると
startPlayer
をコメントアウトするとコンパイラーエラーが発生しますし、さらに奇妙なことに
10
を
startPlayer
の開始サイズを変更する)適切なレスポンスを返します。
Player
の開始サイズを変更します); また、間違ったタイプであるにもかかわらず。データ定義が正しく読み込まれていることを確認するために、ファイルにタイプミスを挿入すると、エラーが発生しました。
上の 2 つのスニペットをそれぞれのファイルに貼り付けてみたところ、2 番目のフィールドである
Player
で
startPlayer
は正しくありません。
何がこのようなことを可能にするのでしょうか?Haskellのタイプチェッカーがまさにこれを防ぐべきものだと思うでしょう。
*
私の最初の問題、すなわち半径が等しいはずの2つの円が異なる大きさに描かれているという問題の答えは、半径の1つが実際には負であるということでした。
どのように解決するのですか?
これがコンパイルできる可能性があるのは
Num (Float,Float)
インスタンスが存在する場合です。これは標準ライブラリでは提供されていませんが、あなたが使っているライブラリのいずれかが、何らかの非常識な理由でこれを追加している可能性があります。ghci でプロジェクトをロードして、もし
10 :: (Float,Float)
が動作するかどうか確認し、次に
:i Num
を試してみて、そのインスタンスがどこから来ているのかを見つけて、それを定義した人を怒鳴りつけてください。
追記: インスタンスをオフにする方法はありません。また ではない モジュールからエクスポートしないようにする方法もありません。もしこれが可能であれば、さらに より のコードになります。ここでの唯一の本当の解決策は、そのようなインスタンスを定義しないことです。
関連
-
[解決済み】Haskellでの挿入ソート
-
[解決済み] Haskellです。パターンでのパースエラー
-
[解決済み】type()とisinstance()の違いは何ですか?)
-
[解決済み] Haskell における `mod` と `rem` の違い
-
[解決済み] Haskellのリストを参照する際の「@」記号の意味は?
-
[解決済み] GHCiの複数行コマンド
-
[解決済み] GHCはなぜこんなに大きいのか/大きいのか?
-
[解決済み] なぜ依存型でないのか?
-
[解決済み] Haskellの派生はどのように行われるのですか?
-
[解決済み] Real World 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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] 解釈の仕方 (Eq a)
-
[解決済み] Hindley-Milnerのどの部分が理解できないのでしょうか?
-
[解決済み] モナドはエンドファンクタのカテゴリではただのモノイドですが、何か問題でも?
-
[解決済み] フリーモナドとは何ですか?
-
[解決済み] Haskellにはなぜ "data "と "newtype "があるのですか?重複] [重複] [重複
-
[解決済み] CabalとStackの違いは何ですか?
-
[解決済み] リーダーモナドの目的は何ですか?
-
[解決済み] Haskell エラー 入力 `=' のパースエラー
-
[解決済み] Haskellの「何もしない」関数、idはなぜ大量のメモリを消費するのか?
-
[解決済み] Real World Haskellのどの部分が今となっては時代遅れ、あるいはバッドプラクティスと考えられているのでしょうか?