Reputation: 5385
I'm trying to define a function to return each of the nth roots of unity.
This compiles,
unity n = map (cis.(*2).(*pi).(/n)) [0..(n-1)]
but its type defaults to unity :: (Enum a, Floating a) => a -> [Complex a]
.
Of course, n
needs to be an integer, as roots of unity aren't defined otherwise; but the returned Complex numbers will necessarily have floating-point coordinates; i.e, they cannot be Complex Int
s. However, the following code won't compile
unity :: (Integral a, Floating b) => a -> [Complex b]
unity n = map (cis . (* 2) . (* pi) . (/ n)) [0..(n - 1)]
because (/)
(*)
and cis
each constrain the return type (or Complex coordinate type in the case of cis
) to be the same as the parameter type; so I get the error
Couldn't match expected type ‘b’ with actual type ‘a’
Is there a way I can force the parameter to be an integer without forcing the complex numbers to have integral components?
Upvotes: 2
Views: 79
Reputation: 5385
All you need to do is coerce your Integral
parameter to a Num
with fromIntegral
when your code expects a value of the same type as the return type, i.e. as arguments to cis
, (*)
or (/)
. Though n
is only directly passed into (/)
, so that's all you need to worry about:
unity :: (Integral a, Floating b) => a -> [Complex b]
unity n = map (cis . (* 2) . (* pi) . (/ (fromIntegral n)) . fromIntegral) [0..(n-1)]
Upvotes: 4