
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 where 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
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?