Haskell 方法是使用不同的类型Complex Float
而Complex 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 Int
, Complex Double
,Complex Rational
等。实际上它甚至定义了Complex (Complex Int)
.
请注意,这并未定义如何将 a 添加Complex Int
到 a Complex Double
。加法 (+) 仍然具有类型(+) :: a -> a -> a
,因此您只能将 a 添加Complex Int
到 aComplex Int
并将 a添加Complex Double
到 another 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 让“用户”决定表达式应该被评估为什么数字类型。