9

Haskellを学んでいます。基数 'b' で 'n' までの乗算表を返す関数を作成しました。数値は「w」桁までパディングされます。最後のステップとして、「w」を自動的に計算したいと思います。なぜこれはコンパイルされないのですか?

-- Number of digits needed for the multiplication table n*n in base 'base'
nOfDg :: Int -> Int-> Int 
nOfDg n base = 1 + floor ( logBase base (n*n)) 

エラー:

No instance for (Floating Int)
     arising from a use of `logBase' at C:\haskel\dgnum.hs:4:24-38
   Possible fix: add an instance declaration for (Floating Int)
   In the first argument of `floor', namely `(logBase b (n * n))'
   In the second argument of `(+)', namely `floor (logBase b (n * n))'
   In the expression: 1 + floor (logBase b (n * n))
4

3 に答える 3

13

logBase は、浮動型クラスを実装する 2 つのパラメーターを取ります。パラメータを logBase に渡す前に、そのパラメータで fromIntegral を呼び出す必要があります。これは6.10.3でコンパイルされました:

nOfDg :: Int -> Int-> Int
nOfDg n base = 1 + floor ( logBase (fromIntegral base) (fromIntegral (n*n)))

Haskell は非常に強く型付けされていることを覚えておく必要があります。そのため、関数に指定された Int パラメーターが、ログ関数が一般的に取る浮動小数点数に自動的に強制されると想定することはできません。

于 2009-12-28T17:22:41.350 に答える
5

logBase浮動小数点型で動作するように宣言されています。Intは浮動小数点型ではなく、Haskellには自動変換はありません。これを試して:

-- Number of digits needed for the multiplication table n*n in base 'base'
nOfDg :: Int -> Float -> Int
nOfDg n base = 1 + floor (logBase base (fromIntegral (n*n)))
于 2009-12-28T17:27:45.747 に答える
3

プレリュードから:

logBase :: Floating a => a -> a -> a

これは、logBaseを使用するには、フローティングタイプを使用する必要があることを意味します。ただし、Intは浮動型ではなく、数値型の自動変換も行われないため、Intから浮動型に変換する必要があります。

nOfDg n base = 1 + floor ( logBase (toEnum base) (toEnum n))

toEnum関数は、パラメーターとしてintを取り、「Enum」型を返します。良い点は、FloatがEnumのインスタンスであるため、それを使用できることです。

toEnum :: Enum a => Int -> a

数値型(Num、Fractional、Integral、Floating ...)の標準型クラスについては、コードでポップアップすることが多いため、変換の学習が役立つ場合があるため、読んだり文書化したりする必要があります。

編集:このHaskell Wiki Bookは、数値型を含む標準型クラス間の関係の非常に便利なグラフィックを提供します。

于 2009-12-28T17:28:21.580 に答える