Haskell 如何从整数转换为小数
假设我有以下Haskell类型描述:Haskell 如何从整数转换为小数,haskell,types,casting,Haskell,Types,Casting,假设我有以下Haskell类型描述: divide_by_hundred :: Integer -> IO() divide_by_hundred n = print(n/100) 为什么当我试图通过ghc运行时,我得到: No instance for (Fractional Integer) arising from a use of `/' Possible fix: add an instance declaration for (Fractional Integer) In t
divide_by_hundred :: Integer -> IO()
divide_by_hundred n = print(n/100)
为什么当我试图通过ghc运行时,我得到:
No instance for (Fractional Integer) arising from a use of `/'
Possible fix: add an instance declaration for (Fractional Integer)
In the first argument of `print', namely `(n / 100)'
In the expression: print (n / 100)
In an equation for `divide_by_hundred':
divide_by_hundred n = print (n / 100)
通过运行:t(/)
我得到:
对我来说,这意味着(/)可以接受任何可以表示为分数的Num(我觉得应该包括整数,尽管我不确定如何验证),只要/
的两个输入是相同类型的
这显然是不准确的。为什么?如何编写一个简单的函数将整数除以100?您可以使用
div
进行整数除法:
div :: Integral a => a -> a -> a
或者您可以使用from integral
将整数转换为分数:
fromIntegral :: (Integral a, Num b) => a -> b
因此,本质上:
divide_by_hundred :: Integer -> IO()
divide_by_hundred n = print $ fromIntegral n / 100
整数不实现分数,这一点您可以在中看到。Haskell喜欢保持运算符在数学上被接受的含义
/
应该是乘法的倒数,但例如5/4*4
不可能为分数整数
实例1生成5
因此,如果您实际上想进行截断整数除法,那么该语言强制您2通过使用div
或quot
来明确表示。OTOH,如果您确实希望结果是分数,您可以使用/
fine,但首先需要转换为具有分数
实例的类型。比如说,
前奏曲>让x=5前奏曲>:t x
x::整数
前奏曲>设y=from积分x/100
前奏曲>y
5.0e-2
序曲>:t y
y::双倍
注意,GHCi在这里选择了
Double
实例,因为这是simples的默认值;你也可以这样做
前奏曲>设y'=从积分x/100::有理数前奏曲>y'
1%20
1严格地说,由于浮点故障,
Double
实例也不太适用此反向标识,但至少大致如此
2实际上,不是语言,而是标准库。你可以定义
instance Fractional Integer where
(/) = div
你自己,那么你的原始代码就可以正常工作了。只是,这是个坏主意 请养成将此类测试作为纯函数编写的习惯,而不是在
IO
monad中编写。除其他优点外,这使得返回类型显式(print
隐藏该类型),从而提供更多的控制另外,请注意,camelCase是Haskeller的惯例。因此,您应该真正拥有dividebyhundle::Integer->Integer
,或者dividebyhundle::(分数f)=>Integer->f
。如何在使用fromIntegral将其转换为分数后将其转换回字符串?
instance Fractional Integer where
(/) = div