<br><font size=2 face="sans-serif">Hi,</font>
<br>
<br><font size=2 face="sans-serif">I'm new to Haskell and even newer to
this list. I have over 20 years of experience in C or C++.</font>
<br>
<br><font size=2 face="sans-serif">For fun, I decided to write a Fourier
transform in Haskell. It would be convenient if I had a function
that converts any real or complex number into a complex number. My
attempt at doing this is below. Hugs produces errors when I try to
load this code.</font>
<br>
<br><font size=2 face="sans-serif">Essentially, I'm trying to define a
class called ConvertibleToComplex. There is a function in this class
called toComplex. toComplex has the type:</font>
<br>
<br><font size=2 face="sans-serif">class ConvertibleToComplex a where</font>
<br><font size=2 face="sans-serif"> toComplex :: RealFloat
b => a -> Complex b</font>
<br>
<br><font size=2 face="sans-serif">I'd like some instances of toComplex
to return a Complex Double while other instances return a Complex Float.
Doing this sort of thing in C++ is fairly easy. However, I
get the feeling that I'm pushing the Haskell type system to do something
it isn't designed to do. Is there a way to define ConvertibleToComplex
so that toComplex's return type is generic and a particular instance of
ConvertibleToComplex decides what the return type is?</font>
<br>
<br><font size=2 face="sans-serif">Here is my attempt at doing this. If
someone can give me some pointers on how to make this work, I'd appreciate
it.</font>
<br>
<br>
<br><font size=2 face="sans-serif">module Main where</font>
<br>
<br><font size=2 face="sans-serif">import Complex</font>
<br>
<br><font size=2 face="sans-serif">--------------------------------------------------------------------------------</font>
<br><font size=2 face="sans-serif">-- toComplex should convert a real or
complex number to a complex number.</font>
<br><font size=2 face="sans-serif">--</font>
<br><font size=2 face="sans-serif">-- Here's my goal for the type of toComplex.
Given:</font>
<br><font size=2 face="sans-serif">-- f :: Float</font>
<br><font size=2 face="sans-serif">-- d :: Double</font>
<br><font size=2 face="sans-serif">-- cf :: Complex Float</font>
<br><font size=2 face="sans-serif">-- cd :: Complex Double</font>
<br><font size=2 face="sans-serif">--</font>
<br><font size=2 face="sans-serif">-- When toComplex is applied to these,
I'd like it to evaluate to the </font>
<br><font size=2 face="sans-serif">-- following types:</font>
<br><font size=2 face="sans-serif">--</font>
<br><font size=2 face="sans-serif">-- toComplex f :: Complex Float</font>
<br><font size=2 face="sans-serif">-- toComplex d :: Complex Double</font>
<br><font size=2 face="sans-serif">-- toComplex cf :: Complex Float</font>
<br><font size=2 face="sans-serif">-- toComplex cd :: Complex Double</font>
<br>
<br>
<br><font size=2 face="sans-serif">class ConvertibleToComplex a where</font>
<br><font size=2 face="sans-serif"> toComplex :: RealFloat
b => a -> Complex b</font>
<br><font size=2 face="sans-serif"> </font>
<br><font size=2 face="sans-serif">-- If I uncomment the following code,
Hugs produces errors:</font>
<br><font size=2 face="sans-serif">-- ERROR "c:\tmp\test2.hs":29
- Inferred type is not general enough</font>
<br><font size=2 face="sans-serif">-- *** Expression : toComplex</font>
<br><font size=2 face="sans-serif">-- *** Expected type : (ConvertibleToComplex
Float, RealFloat a) => Float -> Complex a</font>
<br><font size=2 face="sans-serif">-- *** Inferred type : (ConvertibleToComplex
Float, RealFloat Float) => Float -> Complex Float
</font>
<br><font size=2 face="sans-serif">{-</font>
<br><font size=2 face="sans-serif">instance ConvertibleToComplex Float
where</font>
<br><font size=2 face="sans-serif"> toComplex
f = f :+ 0</font>
<br>
<br><font size=2 face="sans-serif">instance ConvertibleToComplex Double
where</font>
<br><font size=2 face="sans-serif"> toComplex
d = d :+ 0</font>
<br>
<br><font size=2 face="sans-serif">instance ConvertibleToComplex (Complex
a) where</font>
<br><font size=2 face="sans-serif"> toComplex
c = c</font>
<br><font size=2 face="sans-serif">-}</font>
<br>