2014-01-26 1 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 $ Real 0.0 비슷한으로 ComplexNumber 객체를 구성합니다.

질문은 Complex Number을 만드는 방법입니다. Number의 모든 유형에는 Complex 인스턴스가 있으므로 deriving ComplexNumber에 그냥 추가 할 수 있습니까?

+0

'con2 (Complex Float)'형식의'ComplexNum'을'con3 (Complex Rational)'형식 중 하나에 추가 할 수있을 것이라고 어떻게 예상합니까? –

+0

@Tom 이러한 함수를 직접 제공하여 ("승격"/ 형식 변환 등) - Number는 Int, Integer 등 원하는 모든 숫자 표현을 포함하며 Number에 대해 소수를 인스턴스화 한 다음 자체 클래스를 인스턴스로 제공합니다 분수 A => 분수 (복소수 a)'. 나는 누군가가 내 자신의 Data.Complex 대신 이것을 사용하는 방법을 알기를 바랬다. – user3125280

+0

@ user3125280 이유가 무엇입니까? 유형에 대한 지식과 통제력의 상실로 인해 귀하는 무엇을 얻게됩니까? –

답변

0

이것은 합법적 인 하스켈 코드가 아닙니다. 형식이 ComplexNum 인 세 개의 생성자가 모두 Complex입니다. 또한 데이터 유형은 대문자로 시작해야하므로 foo은 유효한 유형이 아닙니다. 그것은 당신이 무슨 뜻인지 말해 어렵다,하지만 난 자상 할게요 :

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

미안하지만 내 실수로 그들은 다른 생성자를 가졌지 만 복잡한 정수를 가졌다. , etc. - Data.Complex – user3125280

3
: 당신은 당신이로 fooNumber의 당신의 정의를 유지하고 정의 할 수 있습니다

data Complex a = (a,a) 

유형이있는 경우

하스켈 접근법은 하나의 유형으로 통합하려는 것이 아니라 Complex FloatComplex Int에 대해 다른 유형을 사용하는 것입니다. 타입 클래스를 사용하면 한 번에 이러한 유형을 모두 정의 할 수 있습니다 : 한 번 Complex Int는 등 Complex Double, Complex Rational는 사실조차 Complex (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 Double에 추가하는 방법은 정의하지 않습니다. 더하기 (+)는 여전히 유형이 (+) :: a -> a -> a이므로 Complex IntComplex 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에서보세요.

업데이트 : 귀하의 의견에 응답

, 나는 종류에 더 많은 작업에 덜 집중하는 것이 좋습니다 것입니다.

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)) 
    ... 

하스켈은 "사용자가"결정하자 어떤 의미에서이 모든 숫자 클래스에서 일반 "1/3"값을 나타냅니다

onethird = 1/3 

:

예를 들어,이 정의를 고려 표현식을 평가할 숫자 유형.

+0

에서 Data.Complex를 사용했습니다. 죄송합니다. 코드에서 실수를 저질렀습니다. – user3125280

+0

그래서 Typeclass를 자세히 설명하기 위해 Data.Complex는 이미 존재하며 어떻게 든 ComplexNum을 쓰지 않아도되는지 알고 싶습니다. 아마도 숫자에 대해 Complex를 인스턴스화하고 (+) 등의 함수를 추가하는 것이 가장 쉽습니다. 그것들은 어느 정도 통일 될 필요가 있고, 어떤 실수에 대해서도 복소수를 갖고 싶습니다. – user3125280

+0

답변 됨 - 잘하면 도움이됩니다. – ErikR