2016-11-28 12 views
2
にフローティング

私は定義しようとしています:変換整数

square :: Integer -> Integer 
square = round . (** 2) 

を、私は取得しています:

<interactive>:9:9: error: 
    • No instance for (RealFrac Integer) arising from a use of ‘round’ 
    • In the first argument of ‘(.)’, namely ‘round’ 
     In the expression: round . (** 2) 
     In an equation for ‘square’: square = round . (** 2) 

<interactive>:9:18: error: 
    • No instance for (Floating Integer) 
     arising from an operator section 
    • In the second argument of ‘(.)’, namely ‘(** 2)’ 
     In the expression: round . (** 2) 
     In an equation for ‘square’: square = round . (** 2) 

が、私はまだこの言語で新しいですし、私はのインスタンスを変換することができないように見えます整数に浮動する。誰も私がそうする方法を知っていますか?

答えて

5

これは、エラーメッセージを理解するために、正しいアレックの答え、の付録です。 (**)のタイプは

(**) :: (Floating a) => a -> a -> a 

あるので

(** 2) :: (Floating a) => a -> a 

(リテラル2は、私たちが必要とする任意の数値型を指定できますので)。しかしaIntegerです。関数がIntegerを入力として宣言しているためです。 Integer sがsinのような浮動小数点演算(および任意の実数で累乗)をサポートしていません - 何FloatingIntegerインスタンスが存在しないので、だから今

(** 2) :: Integer -> Integer --provided that there is a `Floating Integer` instance 

これは、2番目のエラーを説明します。

は、その後、あなたは型を持つroundに沿って、Integerでこの関数の出力を渡す

round :: (RealFrac a, Integral b) => a -> b 

我々は、我々が議論したように、それは(** 2)から来ているため、入力、aは、Integer知っている、と関数の出力がIntegerと宣言されているので、出力bIntegerです。だから今は

round :: Integer -> Integer 
    --provided there are `Integral Integer` and `RealFrac Integer` instaces 

を持ってIntegralIntegerインスタンスは、それが使用されているので、そこですが、何のRealFracIntegerインスタンスが存在しない、それはあなたの最初のエラーを説明します。 Integerは、分子を抽出するような合理的な操作をサポートしていません(ただし、私はそれらを...できると思います)。

1

あなたが(ちょうどアレックの優れたソリューション@従うのではなく)エラーを修正したい場合は、@のluquiの答えに付録として、あなたが最初FloatingインスタンスにIntegerパラメータを変換することができます:

square :: Integer -> Integer 
square = round . (** 2) . fromInteger 
+0

ことがありますluquiの答えがAlecの答えに対するコメントに凝縮されていたかどうかは議論の余地がありますが、これは確かにluquiの答えに対するコメントであった可能性があります。 – chepner