Hi,
I'm new to Haskell and even newer to
this list. I have over 20 years of experience in C or C++.
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.
Essentially, I'm trying to define a
class called ConvertibleToComplex. There is a function in this class
called toComplex. toComplex has the type:
class ConvertibleToComplex a where
toComplex :: RealFloat
b => a -> Complex b
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?
Here is my attempt at doing this. If
someone can give me some pointers on how to make this work, I'd appreciate
it.
module Main where
import Complex
--------------------------------------------------------------------------------
-- toComplex should convert a real or
complex number to a complex number.
--
-- Here's my goal for the type of toComplex.
Given:
-- f :: Float
-- d :: Double
-- cf :: Complex Float
-- cd :: Complex Double
--
-- When toComplex is applied to these,
I'd like it to evaluate to the
-- following types:
--
-- toComplex f :: Complex Float
-- toComplex d :: Complex Double
-- toComplex cf :: Complex Float
-- toComplex cd :: Complex Double
class ConvertibleToComplex a where
toComplex :: RealFloat
b => a -> Complex b
-- If I uncomment the following code,
Hugs produces errors:
-- ERROR "c:\tmp\test2.hs":29
- Inferred type is not general enough
-- *** Expression : toComplex
-- *** Expected type : (ConvertibleToComplex
Float, RealFloat a) => Float -> Complex a
-- *** Inferred type : (ConvertibleToComplex
Float, RealFloat Float) => Float -> Complex Float
{-
instance ConvertibleToComplex Float
where
toComplex
f = f :+ 0
instance ConvertibleToComplex Double
where
toComplex
d = d :+ 0
instance ConvertibleToComplex (Complex
a) where
toComplex
c = c
-}