2009-11-11 2 views
4

다음 하스켈 코드에서 어떻게 더 간결하게 작성할 수 있습니까? 네 가지 조건을 모두 열거해야합니까? 아니면 더 컴팩트 한 패턴으로 요약 할 수 있습니까? 예를 들어, Haskell이 float과 int를 어떻게 추가 하는지를 이미 알고있는 방법을 사용할 수 있습니까? 에서까지 수동으로 지정하지 않아도됩니까?Haskell의 패턴 일치 데이터 유형. 지름길?

data Signal = SignalInt Int | SignalFloat Float | Empty deriving (Show) 

sigAdd :: Signal -> Signal -> Signal 
sigAdd (SignalInt a) (SignalInt b) = SignalInt (a + b) 
sigAdd (SignalInt a) (SignalFloat b) = SignalFloat ((fromIntegral a) + b) 
sigAdd (SignalFloat a) (SignalInt b) = SignalFloat (a + (fromIntegral b)) 
sigAdd (SignalFloat a) (SignalFloat b) = SignalFloat (a + b) 

main :: IO() 
main = do 
    putStrLn (show (sigAdd (SignalFloat 2) (SignalInt 5))) 

답변

7

하스켈이하는 하지FloatInt를 추가하는 방법을 알고;

Prelude> (5 :: Int) + 3.5 

<interactive>:1:13: 
    No instance for (Fractional Int) 
     arising from the literal `3.5' at <interactive>:1:13-15 
    Possible fix: add an instance declaration for (Fractional Int) 
    In the second argument of `(+)', namely `3.5' 
    In the expression: (5 :: Int) + 3.5 
    In the definition of `it': it = (5 :: Int) + 3.5 

기능 toFloatSig 정의가 :

다음
toFloatSig (SignalInt a) = fromIntegral a 
toFloatSig (SignalFloat a) = a 

당신이 쓸 수 있습니다 :

sigAdd (SignalInt a) (SignalInt b) = SignalInt (a + b) 
sigAdd sa sb = SignalFloat (toFloatSig sa + toFloatSig sb) 

것은 또한 Signal 인스턴스를 만들기 위해 적합 할 수 있습니다 그것은 형식에 대한 매우 구체적이고 명시 적이다 Num class 중 하나이므로 + 연산자를 사용하여 직접 추가 할 수 있습니다. 또한, 유형이 더 일반적인 만들 수 :

data (Num a) => Signal a = Signal a | Empty deriving (Show) 
+0

> sigAdd SA SB = SignalFloat (toFloatSig A + toFloatSig 나) 이 될해야 "... (toFloatSig SA + toFloatSig SB)"? 감사. – Steve

+0

네가 맞아. 고마워. – Thomas

+1

나는 Signal Num을 만들기 위해 확실히 노력할 것입니다. –