[Haskell-beginners] Re: (Integral b, RealFrac b) to Int
daniel.is.fischer at web.de
Tue Feb 9 07:23:50 EST 2010
Am Dienstag 09 Februar 2010 08:53:13 schrieb han:
> I made a mistake in copying the original code.
> The correct version is:
> line (sx, sy) (tx, ty)
> | abs (sx - tx) > abs (sy - ty) =
> zip xs [round (sy + (sy - ty) * x / xd) | x <- [0 .. xd]]
> | otherwise =
> zip [round (sx + (sx - tx) * y / yd) | y <- [0 .. yd]] ys
> xs = target sx tx
> ys = target sy ty
> xd = abs (sx - tx)
> yd = abs (sy - ty)
The type of (/) is
Prelude> :t (/)
(/) :: (Fractional a) => a -> a -> a
and that of round
Prelude> :t round
round :: (RealFrac a, Integral b) => a -> b
So the expression
(sy + (sy - ty) * x / xd)
forces sy, ty and xd to have the same Fractional type, fr.
Since xd = abs (sx-tx), sx and tx have the same type.
Now you apply round to that expression, which can give you any Integral
type you desire. In the first branch, round (...) becomes the second
component of the result pairs, in the second branch the first component.
Probably target has type
target :: (Num/Integral/? a) => a -> a -> [a]
, which forces all types to be the same, giving the overall type
line :: (Integral b, RealFrac b) => (b, b) -> (b, b) -> [(b, b)]
Usually, no type is an instance of Integral and RealFrac at the same time,
so it's not a usable function.
You want the type
line :: (Int,Int) -> (Int,Int) -> [(Int,Int)]
One way to find out what went wrong is to give that type signature in the
source and see what error message you get.
It will probably be
No instance for (Fractional Int)
arising from a use of `/' at (source location)
Possible fix: add an instance declaration for (Fractional Int)
In the expression: ...
So you can't divide Ints with (/). You can either use the integral division
"div": (sy + (sy - ty) * x `div` xd), or, if the round is important and you
can't use integral division - which gives floor -, convert the arguments to
(/) to a Fractional type before dividing:
(sy + round (fromIntegral ((sy - ty) * x) / fromIntegral xd))
> On Tue, Feb 9, 2010 at 4:40 PM, han <e at xtendo.org> wrote:
> > I have this code:
> > line (sx, sy) (tx, ty)
> > | abs (sx - tx) > abs (sy - ty) =
> > zip xs [(sy + (sy - ty) * x / xd) | x <- [0 .. xd]]
> > | otherwise =
> > zip [(sx + (sx - tx) * y / yd) | y <- [0 .. yd]] ys
> > where
> > xs = target sx tx
> > ys = target sy ty
> > xd = abs (sx - tx)
> > yd = abs (sy - ty)
> > It currently has the inferred type signature of
> > (Integral b, RealFrac b) => (b, b) -> (b, b) -> [(b, b)]
> > and I want it to be
> > (Int, Int) -> (Int, Int) -> [(Int, Int)]
> > which, when coerced, causes an error.
> > Any idea?
More information about the Beginners