Haskell类型/类型转换(sqrt,floor)

时间:2014-11-03 09:31:35

标签: haskell

我尝试使用Haskell实现Cantor配对。一个int列表的编码工作正常,但是由于类型错误,解码只是不起作用。

我尝试了几乎所有我能想到的东西,但没有任何结果可以解决:

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. input是已经解码的Integers
  3. 的列表

    正如您所看到的,我使用的是sqrtfloor等其他内容,所以它有点混乱......

1 个答案:

答案 0 :(得分:4)

确实看起来很绝望。几点:

  1. 你当然不想要fromRational,因为你在这里没有实际的Rational。此外,fromRationaltoFractional都严格不如组合realToFrac,尽管您也不需要 - 这些都是为了在不同之间进行转换浮点/有理类型,但只有一个涉及Double
  2. 您不想要toInteger,这仅适用于在不同Integral类型之间进行转换。您执行希望其概括fromIntegralIntegral类型转换为通用Num
  3. 您应该明确确定哪些变量是Integer,哪些是Double。然后,在必要时,使用fromIntegralInteger转换为Doublefloor或其他类似函数,以便从Double转换为Integer。你有几次尝试在相同的类型之间进行转换(基本上,所有toInteger s。)

    鉴于此,您可以将类型转换代码清理为(为了清晰起见,添加显式类型注释):

    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