2014-11-03 130 views
1

我試圖用Haskell實現Cantor配對。整數列表的編碼工作正常,但由於類型錯誤,解碼不起作用。Haskell類型/類型轉換(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. 輸入與已經解碼的整數
列表

正如你所看到的,我使用sqrtfloor和其他東西,所以它有點凌亂...

+1

您還應該添加遇到的錯誤。 – Zeta 2014-11-03 09:40:29

+0

我認爲你的問題在這裏:'8.0 * e + 1.0'如果我看到它是正確的'e'是一個整數,所以你不能在這裏使用它 - 應該是這樣的:'8.0 * fromInteral e * 1.0' – Carsten 2014-11-03 09:52:25

+0

next問題同一行 - 'fromIntegral'和無論'sqrt'出現什麼......嘗試'sqrt。 fromlteral $ 8 * e + 1'而不是... – Carsten 2014-11-03 09:54:09

回答

4

確定看起來絕望。有幾點:

  1. 你肯定不希望fromRational,因爲你沒有實際Rational這兒。此外,fromRationaltoFractional都嚴格低於其組合realToFrac,雖然你不需要這樣做 - 這些都是用於轉換不同的浮點/合理類型,但你只有一個參與,Double
  2. 你不想要toInteger,它只是用於在不同的Integral類型之間轉換。您希望其泛化fromIntegral它將從Integral類型轉換爲一般Num

您應該明確地決定您的哪些變量是Integer s,哪些是Double s。然後使用fromIntegralInteger轉換爲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 2014-11-03 10:10:09

+0

@CarstenKönig我不同意,這意味着本質上是非法的純粹的數學符號,因爲一個愚蠢的哈斯克爾違約問題沒有真正的後果。 – 2014-11-03 10:13:06

+0

這是你的答案 - 我只是喜歡我的代碼沒有警告 - 這就是爲什麼我添加了IMO – Carsten 2014-11-03 10:20:19