2016-04-01 9 views
1

okです:宣言種類Haskellでエラーが発生しますが、私は次のコード<code>runhaskell</code>すると宣言することはない

f :: Num a => a -> a -> a 
f x y = x*x + y*y 

x = 3 
y = 2.3 
main = print (f x y) 

すべての罰金を。私は、xとyの割り当て上記の型宣言を追加する場合でも:

x :: Int 
y :: Float 

を私はエラーを取得:「期待タイプInt' with actual typeフロート 'と一致しませんでした」。

私はfの型を宣言するとき、私はxとyが同じ型でなければならないことを誇張していることを理解しています。私が理解していないのは、最初のケースでうまくいく理由です。

は私が

Prelude> let x = 3 
Prelude> :type x 
x :: Integer 
Prelude> let y = 2.3 
Prelude> :type y 
y :: Double 

xとyを得るGHCiの中に割り当てを実行し、タイプを問い合わせる場合は、型が宣言されていない場合、異なる種類の数として解釈されます!なぜ、fはエラーを投げないのですか?

+0

これは、GHCiののかなり古いバージョンのように聞こえます。最近のバージョンでは、対話モード*でデフォルトで*の単相性制限が無効になり、動作が良くなりました。 – dfeuer

+0

私は 'sudo apt-get install haskell-platform'を使ってhaskellプラットフォームをダウンロードしました... – Pigna

+0

それはおそらく古いでしょう。しかし見る方法は '--version'です。 – dfeuer

答えて

4

これは、次の三つの混乱相互作用である:Haskellでは

  • 数値リテラルは、多型です:

    Prelude> :type 3 
    3 :: Num a => a 
    Prelude> :type 2.3 
    2.3 :: Fractional a => a 
    
  • Monomorphism restrictionが多型であることから、あなたのxyを禁止します。ことではなく、あなたを与えるの「あいまいなタイプ」のエラーコンパイラが働き、あなたのxy具体的な種類を与えるために最善をしようとしますので、

  • Defaulting mechanismはそれを作ります。あなたのghciセッションでは、さまざまなタイプが動作しますが、メインプログラムのIntegerでは動作しませんので、両方に対してDoubleを選択します。

2

GHCiには、GHCiで直接定義されたバインディングの数値型のための特殊なデフォルトルールがあります。

あなたはむしろ:loadモジュール、その後、GHCiのを確認する必要があり、エクスポートのバインディングのためのタイプ:

> :load Foo.hs 
> :type x 
> :type y 
関連する問題