あなたの問題は、あなたはそれをさまざまな方法で修正しようとしましたが、あなたは何かをしようとしなかったということですx
。それはまさにあなたの問題が存在するところです。次のタイプを見てみましょうsqrt
:
Prelude> :t sqrt
sqrt :: (Floating a) => a -> a
一方、x
はでありInt
、GHCiにについての情報を求めると、次のようFloating
になります。
Prelude> :info Floating
class (Fractional a) => Floating a where
pi :: a
<...snip...>
acosh :: a -> a
-- Defined in GHC.Float
instance Floating Float -- Defined in GHC.Float
instance Floating Double -- Defined in GHC.Float
したがって、 sとsのタイプのみFloating
です。他の方向と同じように、をに変換する方法が必要です。このようなタイプの質問があるときはいつでも、タイプを検索するHaskell検索エンジンであるHoogleに尋ねることができます。残念ながら、を検索すると、お粗末な結果が得られます。しかし、私たちが探しているものをリラックスさせたらどうなるでしょうか?を検索すると、ほぼ正確に必要な関数があることがわかります。そして、型をまで緩和すると、関数があることがわかります。Float
Double
Int
Double
floor :: (RealFrac a, Integral b) => a -> b
Int -> Double
Integer -> Double
fromInteger :: Num a => Integer -> a
(Integral a, Num b) => a -> b
fromIntegral :: (Integral a, Num b) => a -> b
したがって、整数の平方根を計算するには、を使用するfloor . sqrt $ fromIntegral x
か、を使用します
isqrt :: Integral i => i -> i
isqrt = floor . sqrt . fromIntegral
sqrt
あなたは;の出力のために正しい方向で問題について考えていました。浮動小数点数を返しましたが、整数が必要でした。ただし、Haskellにはサブタイピングや暗黙のキャストの概念がないため、入力も変更する必要がありsqrt
ます。
他の懸念事項のいくつかに対処するには:
intSqrt :: Int -> Int
intSqrt x = floor (sqrt (x + 0.0))
あなたはこれを「ナンセンス」と呼んでいるので、それが機能することを期待していないことは明らかですが、なぜそうではないのですか?問題は、(+)
タイプがあるNum a => a -> a -> a
ことです。同じタイプのものを2つしか追加できません。これは、5×5の実数行列に複素数を追加できないことを意味するため、一般的には適切です。ただし、0.0
のインスタンスである必要があるため、Fractional
に追加することはできませんx :: Int
。
(sqrt 500)は正常に機能しているようです…</ p>
500
のタイプが期待したものではないため、これは機能します。信頼できる仲間のGHCiに聞いてみましょう。
Prelude> :t 500
500 :: (Num t) => t
実際、すべての整数リテラルにはこのタイプがあります。これらは任意の種類の数値にすることができます。これは、Num
クラスに関数が含まれているために機能しますfromInteger :: Integer -> a
。したがって、あなたが書いたとき、GHCはそれが満たされる必要がsqrt 500
あることに気づきました(そしてそれはデフォルトのルールのおかげでそのような数値タイプを暗黙的に選択します)。同様に、上記はの関数のおかげでタイプがあります。500
500 :: (Num t, Floating t) => t
Double
0.0
Fractional t => t
Fractional
fromRational :: Rational -> a
…しかし(sqrt x)はxがフローティングであると主張しています…</ p>
のタイプを見る上記を参照してくださいsqrt
。
…そして、Intを実数に変換するために見つけることができる関数はありません…。
さて、あなたは今それを持っています:fromIntegral
。なぜあなたがそれを見つけられなかったのか分かりません。どうやらHoogleは、関数の汎用タイプのおかげで、私が予想していたよりもはるかに悪い結果をもたらします。
なんでこんなに難しいの?
あなたが持っているので、もうそうではないことを願っていますfromIntegral
。