0

Haskellでは、引数の型が必要な型と一致しないため、関数の定義に問題があります。

たとえば、を取り、の平方根のn :: Int1からの整数のリストを生成する関数を作成したいと思います。したがって、次のような関数が必要になります。floorn

list :: Int -> [Int]

もともと私は関数を次のように定義しました:

list :: Int -> [Int]

list n = [1 .. floor (sqrt n)]

sriptをロードすると、タイプが一致しないというエラーメッセージが表示されます。sqrtただし、関数のタイプまたは関数のタイプが一致していないかどうかはわかりませんfloor。エラーメッセージは次のとおりです。

No instance for (Floating Int)
  arising from a use of 'sqrt' at pe142.hs:6:22-27
Possible fix: add an instance declaration for (Floating Int)
In the first argument of 'floor', namely '(sqrt n)'
In the expression: floor (sqrt n)
In the expression: [1 .. floor (sqrt n)]
Failed, modules loaded: none.

誰かが私にエラーの原因とそれを修正する方法を説明してもらえますか?

4

4 に答える 4

6

sqrtFloatinga など、クラスの引数が必要Doubleです。Intクラスのインスタンスではないを渡していますFloating-それがエラーメッセージが伝えていることです。

エラーを修正するには、 を呼び出す前に を に変換IntDoubleますsqrtfromIntegralそのために関数を使用できます。

于 2012-09-12T00:09:54.107 に答える
4

これを試すと:

list :: Int -> [Int]
list n = [1 .. floor (sqrt n)]

次のエラーが表示されます。

../src/scratch.hs:15:16:
    No instance for (RealFrac Int)
      arising from a use of `floor'
    Possible fix: add an instance declaration for (RealFrac Int)
    In the expression: floor (sqrt n)
    In the expression: [1 .. floor (sqrt n)]
    In an equation for `list': list n = [1 .. floor (sqrt n)]

../src/scratch.hs:15:23:
    No instance for (Floating Int)
      arising from a use of `sqrt'
    Possible fix: add an instance declaration for (Floating Int)
    In the first argument of `floor', namely `(sqrt n)'
    In the expression: floor (sqrt n)
    In the expression: [1 .. floor (sqrt n)]

これらのエラーの意味は次のとおりです。

  • floor関数は type の引数を受け入れることができませんInt。その引数は「実数」型でなければなりません。(型が整数のみをサポートする数値の下限を求めるのは意味がありません。)
  • sqrt関数は型の引数も受け入れることができませんInt。その引数は浮動小数点型でなければなりません。(平方根は通常無理なので、浮動小数点型が必要です。)

Haskell は、どの数値関数をどの数値型に適用できるか、これらの関数が返す型について非常にうるさいです。また、基本的に暗黙のキャストをまったく実行しません。クラス階層は非常に複雑であるため、私は通常、コンパイラに数値コードの型を推測させようとします。関数の型宣言を省略すると、コンパイラは次の型を推測します。

list :: (Floating a, Integral t, RealFrac a) => a -> [t]

つまり、list関数 function は浮動小数点の「実数」を引数として取り、その結果として整数のリストを生成します。したがって、たとえば、listタイプの引数を取りDouble[Integer].

ただし、型宣言を省略しても、問題が発生しないわけではなく、明示的なキャストを使用する必要があることがよくあります。最も典型的なのは、関数を使用してfromIntegral整数型を小数型にキャストする必要があることです。

于 2012-09-12T00:12:23.447 に答える
1

sqrt には次の型シグネチャがあります。

Floating a => a -> a

これは、sqrt が型 a の引数を取り、型 a の引数を返すことを意味します。制限は、 a が型クラス Floating の型である必要があることです。通常は、Single または Double です。Int は型クラス Floating にはないため、n を型クラス Floating にあるものに変換する必要があります。これを行うには、次の呼び出しを追加しますfromIntegral

list n = [1 .. floor (sqrt (fromIntegral n))]
于 2012-09-12T00:12:30.320 に答える
0

この質問は週に1回程度聞かれます。(それはあなたに対する不満ではなく、ただの観察です。明らかにこれはかなり多くの人々を混乱させます。)

一言で言えば、sqrt整数では機能せず、浮動小数点数でのみ機能します。(たとえば、では機能しませんIntが、では機能しDoubleます。)一部のプログラミング言語では、このような場合、整数は常に浮動小数点数に自動的に「昇格」されます。しかし、Haskellではこれを手動で行う必要があります。

解決策は、他の6人がすでに書いていることは間違いないので、fromIntegral整数から浮動小数点に変換するためにそこに固執することです。あなたはすでにfloorそこにいます、それはあなたが期待するように後であなたが整数に戻すことを可能にします。

于 2012-09-12T11:01:53.023 に答える