我的 sqrt 函数不会在 GHCi 中编译
my sqrt function will not compile in GHCi
我想计算 Int
的平方根,Prelude sqrt
函数用于 Float ⟶ Float
,我需要 Int ⟶ Float
.
尝试推出我自己的简单 sqrt 我定义了两种类型并从 Hackage 上的 Prelude 源代码复制了函数: sqrt x = x ** 0.5
所以:
sqrt' :: Int -> Float
sqrt' x = x ** 0.5
给出错误:
• Couldn't match expected type ‘Float’ with actual type ‘Int’
• In the expression: x ** 0.5
In an equation for ‘sqrt'’: sqrt' x = x ** 0.5
|
19 | sqrt' x = x ** 0.5
| ^^^^^^^^
我尝试了不同类型的 class 定义,使用中间变量和 where 子句等等,但没有成功。
编辑 ⟶
p 285 摘自 The Haskell Book which is a prettier version of the Haskell documentation illustration here.
(**) :: Floating a => a -> a -> a
can only be applied to Floating
类型,并且要求操作数和结果都具有相同的类型。
另一方面,您的类型签名表示 x
是 Int
(Int
是 而不是 的成员Floating
typeclass),而且 x ** 0.5
应该 return a Float
,所以这违反了 (**)
.
的类型签名
我们可以转换属于 Integral
typeclass to any type that is a member of the Num
typeclass with fromIntegral :: (Integral a, Num b) => a -> b
的任何类型。在这种情况下,fromIntegral
会将 Int
转换为 Float
:
sqrt' :: Int -> Float
sqrt' x = <b>fromIntegral</b> x ** 0.5
isqrt :: Int -> Float -- but realy,
-- (Integral a, Floating b) => a -> b
isqrt n = sqrt $ fromIntegral n
首先会起作用。
它的工作原理是sqrt :: Float -> Float
(或Double -> Double
,但实际上
sqrt :: Floating b => b -> b
) 需要它的参数是正确的类型,并且
fromIntegral :: (Integral a, Num b) => a -> b
完成任务。
任何 Integral
类型已经是 Num
任何 Floating
类型也是如此:
> :i Integral
class (Real a, Enum a) => Integral a where -- subclass of Real
......
toInteger :: a -> Integer
> :i Real
class (Num a, Ord a) => Real a where -- subclass of Num
......
> :i Num
class Num a where
......
fromInteger :: Integer -> a
> :i Floating
class Fractional a => Floating a where -- subclass of Fractional
......
> :i Fractional
class Num a => Fractional a where -- subclass of Num
......
我想计算 Int
的平方根,Prelude sqrt
函数用于 Float ⟶ Float
,我需要 Int ⟶ Float
.
尝试推出我自己的简单 sqrt 我定义了两种类型并从 Hackage 上的 Prelude 源代码复制了函数: sqrt x = x ** 0.5
所以:
sqrt' :: Int -> Float
sqrt' x = x ** 0.5
给出错误:
• Couldn't match expected type ‘Float’ with actual type ‘Int’
• In the expression: x ** 0.5
In an equation for ‘sqrt'’: sqrt' x = x ** 0.5
|
19 | sqrt' x = x ** 0.5
| ^^^^^^^^
我尝试了不同类型的 class 定义,使用中间变量和 where 子句等等,但没有成功。
编辑 ⟶
p 285 摘自 The Haskell Book which is a prettier version of the Haskell documentation illustration here.
(**) :: Floating a => a -> a -> a
can only be applied to Floating
类型,并且要求操作数和结果都具有相同的类型。
另一方面,您的类型签名表示 x
是 Int
(Int
是 而不是 的成员Floating
typeclass),而且 x ** 0.5
应该 return a Float
,所以这违反了 (**)
.
我们可以转换属于 Integral
typeclass to any type that is a member of the Num
typeclass with fromIntegral :: (Integral a, Num b) => a -> b
的任何类型。在这种情况下,fromIntegral
会将 Int
转换为 Float
:
sqrt' :: Int -> Float
sqrt' x = <b>fromIntegral</b> x ** 0.5
isqrt :: Int -> Float -- but realy,
-- (Integral a, Floating b) => a -> b
isqrt n = sqrt $ fromIntegral n
首先会起作用。
它的工作原理是sqrt :: Float -> Float
(或Double -> Double
,但实际上
sqrt :: Floating b => b -> b
) 需要它的参数是正确的类型,并且
fromIntegral :: (Integral a, Num b) => a -> b
完成任务。
任何 Integral
类型已经是 Num
任何 Floating
类型也是如此:
> :i Integral
class (Real a, Enum a) => Integral a where -- subclass of Real
......
toInteger :: a -> Integer
> :i Real
class (Num a, Ord a) => Real a where -- subclass of Num
......
> :i Num
class Num a where
......
fromInteger :: Integer -> a
> :i Floating
class Fractional a => Floating a where -- subclass of Fractional
......
> :i Fractional
class Num a => Fractional a where -- subclass of Num
......