Haskell:用于表示二进制,十六进制和八进制的数据类型

时间:2014-08-03 13:44:58

标签: haskell

我正在尝试定义一种数据类型来表示二进制,八进制和十六进制的数字。我的想法是使用这种数据类型定义一些函数,以便从八进制转换为二进制,从二进制转换为十六进制,从八进制转换为十六进制

这就是我现在所拥有的......

data Number = Bin[Char] | Hex[Char]| Oct[Char]
                                          deriving Show

oct2Bin :: Number -> Number
bin2Hex :: Number -> Number
oct2Hex :: Number -> Number

但我被困在这里,我不知道我是否走在正确的轨道上。我很感激能帮到这个问题。

2 个答案:

答案 0 :(得分:4)

您应该简单地将数字保存为数字类型之一,最好是整数。这样,您就可以轻松使用

这样的功能
type Base   = Int
type Number = Integral

repr :: Integral a => Base -> a -> String

但也许已经有这样的功能?事实上,有(Numeric):

showIntAtBase :: (Integral a, Show a) => 
                 a                       -- the base
              -> (Int -> Char)           -- a function to transform single digits
                                         -- (in that base)
              -> a                       -- the number
              -> ShowS                   -- ShowS = String -> String

因此,repr base number只是showIntAtBase base conv number ""

repr base number = showIntAtBase base conv number ""
    where conv n  = (['0'..'9'] ++ ['a'..'z']) !! n

虽然您可能希望将conv更改为其他内容。

此外,Numeric已包含showHexshowOctshowBinary不在那里,但与上面的repr一起就像showBin = repr 2一样简单。

答案 1 :(得分:1)

为什么不使用Int来表示您的号码,当您出于某种原因需要字符串表示时,请使用Number -> String函数?例如:

type Number = Int

toBin :: Number -> String
toOct :: Number -> String
toHex :: Number -> String

toOct = show
... implement others as usual ...

使用像这样的规范表示(在这种情况下,我们的表示形式为Int),您可以最小化类型之间所需的转换。此类型的所有操作都可以无需转换即可运行。只有在需要字符串表示时才会进行转换。

(@Karoly在评论中也提到了组合爆炸的问题,但是只要你保证所有格式都可以传递,我认为你可以避免它 - 即使你的实现效率可能非常低效)