2014-01-26 2 views
-1

У меня есть код, который выглядит немного как следующее:Выведение Data.Complex в Haskell

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 Complex в Number?

+0

Как вы ожидаете, что сможете добавить 'ComplexNum' формы' con2 (Complex Float) 'в один из форм' con3 (Complex Rational) '? –

+0

@Tom, предоставляя эти функции самостоятельно («продвижение»/типы конвертирования и т. Д.). Число включает в себя все представления чисел, которые я хочу использовать как Int, Integer и т. Д., И я буду использовать дробное число для Number, а затем предоставить свой собственный сложный класс с экземпляром Дробный 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 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).

Обратите внимание, что это не определяет, как добавить Complex Int в Complex Double. Дополнение (+) по-прежнему имеет тип (+) :: a -> a -> a, поэтому вы можете только добавить Complex Int в Complex Int и Complex 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.

Update:

В ответ на ваши замечания, я хотел бы предложить больше ориентированы на операции и в меньшей степени на типах.

Для примера рассмотрим следующее определение:

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. Я предполагаю, что это, скорее всего, потребует инстанцирования Complex для числа и добавления функций (+) и т. Д. Их нужно несколько унифицировать, и я хотел бы иметь комплексные числа для любых действительных чисел. – user3125280

+0

Ответ обновлен - надеюсь, это помогает. – ErikR

 Смежные вопросы

  • Нет связанных вопросов^_^