[英]Haskell types/type conversion (sqrt,floor)
我正在嘗試使用Haskell實現Cantor配對。 整數列表的編碼工作正常,但是由於類型錯誤,解碼只是無效。
我幾乎嘗試了所有我能想到的,但沒有任何效果:
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)
如您所見,我正在使用sqrt
, floor
和其他東西,所以有點混亂...
好的,看起來確實很絕望。 幾點:
fromRational
,因為這里沒有實際的Rational
。 另外, fromRational
和toFractional
都比其realToFrac
組合嚴格不通用,盡管您都不需要-它們都用於在不同的浮點/有理類型之間進行轉換,但是您只有一個Double
涉及。 toInteger
,它僅用於在不同的Integral
類型之間進行轉換。 您確實希望將其歸納為fromIntegral
,它將其從Integral
類型轉換為一般Num
。 您應該做出明確的決定,確切地確定哪些變量是Integer
,哪些變量是Double
。 然后在必要時使用fromIntegral
從Integer
轉換為Double
,並使用floor
或其他類似函數從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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.