How do I cast from Integer to Fractional

Let's say I have the following Haskell type description:

divide_by_hundred :: Integer -> IO()
divide_by_hundred n = print(n/100)

Why is it that when I attempt to run this through ghc I get:

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)

By running :t (/) I get:

(/) :: Fractional a => a -> a -> a

which, to me, suggests that the (/) can take any Num that can be expressed as fractional (which I was under the impression should include Integer, though I am unsure as how to verify this), as long as both inputs to / are of the same type.

This is clearly not accurate. Why? And how would I write a simple function to divide an Integer by 100?


Haskell likes to keep to the mathematically accepted meaning of operators. / should be the inverse of multiplication, but eg 5 / 4 * 4 couldn't possibly yield 5 for a Fractional Integer instance1.

So if you actually mean to do truncated integer division, the language forces you2 to make that explicit by using div or quot . OTOH, if you actually want the result as a fraction, you can use / fine, but you first need to convert to a type with a Fractional instance. For instance,

Prelude> let x = 5
Prelude> :tx
x :: Integer
Prelude> let y = fromIntegral x / 100
Prelude> y
5.0e-2
Prelude> :ty
y :: Double

Note that GHCi has selected the Double instance here because that's the simples default; you could also do

Prelude> let y' = fromIntegral x / 100 :: Rational
Prelude> y'
1 % 20


1Strictly speaking, this inverse identity doesn't quite hold for the Double instance either because of floating-point glitches, but there it's true at least approximately.

2Actually, not the language but the standard libraries. You could define

instance Fractional Integer where
  (/) = div

yourself, then your original code would work just fine. Only, it's a bad idea!


You can use div for integer division:

div :: Integral a => a -> a -> a

Or you can convert your integers to fractionals using fromIntegral :

fromIntegral :: (Integral a, Num b) => a -> b

So in essence:

divide_by_hundred :: Integer -> IO()
divide_by_hundred n = print $ fromIntegral n / 100

Integers do not implement Fractional, which you can see in the manual.

链接地址: http://www.djcxy.com/p/33154.html

上一篇: Haskell:在函数的不同类型中使用相同的运算符

下一篇: 我如何从整数转换为分数