2014-11-03 2 views
1

하스켈을 사용하여 칸토어 페어링을 구현하려고합니다. int리스트의 인코딩은 정상적으로 작동하지만 디코딩은 타입 에러로 인해 작동하지 않습니다. 하스켈 유형/유형 변환 (sqrt, floor)

은 내가 생각할 수있는 거의 모든 것을 시도했지만 아무것도 해결하지 않을 것이다 :

cantorDecode :: Integer -> [Integer] -> [Integer] 
cantorDecode e zs 
    | length zs == 0 = cantorDecode y [x,y] 
    | head zs == 0  = map toInteger $ tail zs  
    | otherwise   = cantorDecode y ((head zs)-1 : (tail zs) ++ [x,y]) 
     where 
      a = fromRational e 
      w = floor ((s-1.0)/2.0) 
      s = fromIntegral $ sqrt(8.0*e+1.0) :: Double 
      t = fromRational $ (w^2+w)/2.0 
      y = toInteger $ e - (toInteger $ floor t) 
      x = toInteger $ (toInteger w) - (toInteger y) 
  1. 입력
  2. 입력을 디코딩하는 다음 정수입니다 이미 정수
에게 디코딩과 목록입니다

보시다시피, 저는 sqrt, floor 및 다른 것들을 사용하고 있습니다. 그래서 좀 더러워졌습니다.

+1

발생하는 오류도 추가해야합니다. – Zeta

+0

당신의 문제가 여기에 있다고 생각합니다 :'8.0 * e + 1.0'이 맞다면'e'는 정수이므로 여기서는 사용할 수 없습니다 - 다음과 같이'8.0 * fromIntegral e * 1.0' – Carsten

+0

다음과 같이하면됩니다. 문제는 같은 줄 -'fromIntegral'과'sqrt'에서 생긴 것 ...'sqrt를 시도하십시오. fromIntegral $ 8 * e + 1' 대신 ... – Carsten

답변

4

절망적 인 확인. 몇 포인트 : 여기에 실제 Rational의이 없기 때문에

  1. 당신은 확실히, fromRational 싶지 않아요. 또한 fromRationaltoFractional은 모두 realToFrac 조합보다 일반적으로 덜 일반적입니다.이 중 하나는 필요하지 않지만 부동 소수점/유 형 유형이 다르지만 하나만 포함하면 Double입니다.
  2. 다른 Integral 유형간에 변환하는 경우에만 toInteger을 원하지 않습니다. 당신은 으로하고 을 Integral 타입에서 일반 Num으로 변환하고 싶습니다.

어떤 변수가 Integer이고 어느 것이 정확히 Double인지 명확히 결정해야합니다. 그런 다음 fromIntegral을 사용하여 Integer에서 Doublefloor 또는 Double에서 Integer으로 변환하는 다른 유사한 기능을 필요에 따라 변환하십시오. 당신은 같은 유형 사이의 변환을가 여러 번 시도해야

이를 감안할 때, 당신은 (명확성을 위해 명시 적 유형의 주석을 추가)들로 당신의 유형 변환 코드를 청소할 수 있습니다 (기본적으로 모든 toInteger들.) :

cantorDecode :: Integer -> [Integer] -> [Integer] 
cantorDecode e zs 
    | length zs == 0 = cantorDecode y [x,y] 
    | head zs == 0  = tail zs  
    | otherwise   = cantorDecode y ((head zs)-1 : (tail zs) ++ [x,y]) 
     where 
      w = floor ((s-1.0)/2.0)    :: Integer 
      w' = fromIntegral w     :: Double 
      s = sqrt(8.0*fromIntegral e+1.0) :: Double 
      t = (w'^2+w')/2.0     :: Double 
      y = e - floor t      :: Integer 
      x = w - y       :: Integer 
+1

마지막 경고를 제거하려면'w '^ 2'를'w'^ (2 :: Integer)'로 변경해야합니다. IMO – Carsten

+0

@ CarstenKönig 나는 반대합니다. 실제 결과가 없다는 바보 같은 하스켈 디폴트 문제 때문에 평범한 수학 표기법. –

+0

그것은 당신의 대답입니다 - 저는 코드에 경고가 없기 때문에 IMO를 추가 한 이유가 – Carsten