2014-01-26 229 views
-1

派生Data.Complex我有一些代码看起来有点像下面这样:哈斯克尔

import Data.Complex 

data Foo = N Number 
     | C ComplexNum 

data Number = Int Integer 
      | Real Float 
      | Rational Rational 
    deriving Show 

data ComplexNum = con1 (Complex Integer) 
       | con2 (Complex Float) 
       | con3 (Complex Rational) 
    deriving Show 

但是这似乎是一个不错的方法来做到这一点。我宁愿有

data Foo = N Number 
     | C (Complex Number) 

并构造ComplexNumber与类似ComplexNumber $ Real 0.0类似的东西。

问题是如何使Complex Number成为可能。由于Number中的所有类型都有相应的Complex实例,我可以只添加deriving ComplexNumber

+0

您如何期待能够将形式为'con2(Complex Float)'的'ComplexNum'添加到形式'con3(Complex Rational)'之一? –

+0

@Tom通过自己提供这些函数(“促进”/转换类型等) - 数字包括我想要的所有数字表示形式,例如Int,Integer等,我将实例分数为Number,然后用'instance创建我自己的复杂类小数A =>小数(复数a)'。我希望有人会知道如何使用Data.Complex而不是我自己做到这一点。 – user3125280

+0

@ user3125280为什么?这种对类型的知识和控制的丧失会增加你的收益? –

回答

0

这似乎不是合法的Haskell代码。您有三个ComplexNum类型的构造函数,全部命名为Complex。此外,数据类型必须以大写字母开头,因此foo不是有效的类型。这很难说你的意思,但我还是要一刺:如果你有一个类型

data Complex a = (a,a) 

你可以保持您定义的Number并定义foo

data Foo = N Number 
     | C (Complex Number) 
+0

对不起我的错误,他们有不同的构造函数,但类型复杂Integer等 - 从Data.Complex – user3125280

3

Haskell的方法是为Complex FloatComplex Int设置不同的类型,而不是试图将它们统一为一种类型。随着类型类,你可以一次定义所有这些类型的:

data Complex a = C a a 

instance Num a => Num (Complex a) where 
    (C x y) + (C u v) = C (x+u) (y+v) 
    (C x y) * (C u v) = C (x*u-y*v) (x*v+y*u) 
    fromInteger n = C (fromInteger n) 0 
    ... 

这一次定义Complex IntComplex DoubleComplex Rational等。事实上它甚至定义Complex (Complex Int)

请注意,这并未定义如何将Complex Int添加到Complex Double。加法(+)仍然有(+) :: a -> a -> a类型,因此只能将Complex Int加到Complex IntComplex Double加到另一个Complex Double

为了增加你必须明确地将它们转换不同类型的数字,例如:

addIntToComplex :: Int -> Complex Double -> Complex Double 
addIntToComplex n z = z + fromIntegral n 

看一看http://www.haskell.org/tutorial/numbers.html部分10.3 Haskell的数字类型类之间更有效的转化功能。

更新:

在回答您的意见,我建议更多的行动和更少的重点类型。

例如,考虑这样的定义:

onethird = 1/3 

这代表了所有号码类通用的 “1/3” 值:

import Data.Ratio 

main = do 
    putStrLn $ "as a Double: " ++ show (onethird :: Double) 
    putStrLn $ "as a Complex Double: " ++ show (onethird :: Complex Double) 
    putStrLn $ "as a Ratio Int: " ++ show (onethird :: Ratio Int) 
    putStrLn $ "as a Complex (Ratio Int): " ++ show (onethird :: Complex (Ratio Int)) 
    ... 

在某种意义上Haskell中,让我们的 “用户” 决定什么样的数字表达式应该被评估为。

+0

我使用Data.Complex,抱歉 - 我也犯了一些代码错误,我会更新它。 – user3125280

+0

因此,为了详细说明类型类Data.Complex已经存在,我想知道是否可以避免写出ComplexNum。我想这很可能会涉及复杂的数字和添加(+)等功能。他们需要统一一些,我想有任何实数的复数。 – user3125280

+0

答复更新 - 希望它有帮助。 – ErikR