You are not logged in.
Hi everyone,
I'm currently working through Write yourself a Scheme in 48 hours and doing the exercises.
One of the exercises is implementing a parser for the complex type. I found a (messy) solution when using two doubles for the real and imaginary part, but I can't figure out how to use Haskell's Complex type.
Simplified, the problematic code is the following:
data LispVal = Ratio Rational
| Complex Double Double
When I try to use "Complex" instead of "Double Double", I get the following error:
`Complex' is not applied to enough type arguments
Expected kind `?', but `Complex' has kind `* -> *'
In the data type declaration for `LispVal'
I don't understand above error message, but my understanding is that "Rational" is a type conversion (or something similar) from floating point for the class Ratio, whilst there's no such equivalent for the class Complex. How would I go on to write such a type conversion from two Double for Complex?
Prelude Complex Ratio> :t 0:+1
0:+1 :: (RealFloat t) => Complex t
Prelude Complex Ratio> :t (0.5 :: Rational)
(0.5 :: Rational) :: Rational
Prelude Complex Ratio> :t (0 % 2)
(0 % 2) :: (Integral t) => Ratio t
Last edited by wuischke (2009-12-13 19:37:59)
Offline
Try this code.
data LispVal = Ratio Rational | Complex Double
Offline
Complex is the "constructor" of LispVal
let l1 = Complex 5.0 5.0
:info l1
EDIT: Maybe this will help a little more:
test.hs:
data LispVal = Ratio Rational | Complex Double Double deriving (Show)
l1 = Ratio 2
l2 = Complex 5.0 3.0
testLisp :: LispVal -> String
testLisp (Ratio x) = "I'm rational:" ++ show x
testLisp (Complex x y) = "We're complex: " ++ show x ++ " " ++ show y
ghci:
*Main> :load test.hs
*Main> testLisp l1
"I'm rational:2 % 1"
*Main> testLisp l2
"We're complex: 5.0 3.0"
Last edited by VirtualRider (2009-12-13 17:15:22)
Offline
Thanks a lot for your answers. I'm afraid I may have posed my question insufficiently and stripped down too much, sorry. My code works fine when I represent a complex number as two doubles, I've written a Parsec parser and a showVal function, both of which work fine.
On the other hand, the Haskell library already contains a Complex type, see http://haskell.org/onlinereport/complex.html. I want to use this complex type instead of a tuple of two Doubles to represent a complex number. The infix constructor is :+, so <num1> :+ <num2> creates such a complex number.
I've tried:
module Main where
import Complex
data DerivedComplex = DComplex Complex
Result:
test.hs:4:31:
`Complex' is not applied to enough type arguments
Expected kind `?', but `Complex' has kind `* -> *'
In the data type declaration for `DerivedComplex'
Also the infix constructor:
data DerivedComplex = DComplex :+
Result:
test.hs:5:0: parse error (possibly incorrect indentation)
And the constructor as it is written in above linked library report:
data DerivedComplex = DComplex Complex((:+))
Result:
test.hs:4:39: Not in scope: type constructor or class `:+'
How would I tell Haskell that my LispVal type may contain Complex numbers as found in this module?
Offline
It's defined as "data (RealFloat a) => Complex a" so you have to specify the content-type:
data DerivedComplex = DComplex (Complex Double)
let d1 = DComplex (5.0 :+ 3.0)
Offline
Wow, thanks for your fast answer, this solved indeed my problem. (And caused a couple new ones, but those I'll try to fight alone first.)
Edit: Thanks to you, there's now finally an acceptable answer for Exercise 7 in Section 3: http://en.wikibooks.org/wiki/Write_Your … Exercise_7
Last edited by wuischke (2009-12-13 18:36:36)
Offline