假设我为十六进制字符串定义了以下类型:
data HexDigit
= H0 | H1 | H2 | H3
| H4 | H5 | H6 | H7
| H8 | H9 | HA | HB
| HC | HD | HE | HF
Hex : Type
Hex = List HexDigit
这种类型非常简单,但在编译为JS后端时可能效率低下。表示十六进制字符串的另一种方法是使用本机string
类型的子集:
data IsNib : Char -> Type where
IsNib0 : IsNib '0'
IsNib1 : IsNib '1'
IsNib2 : IsNib '2'
IsNib3 : IsNib '3'
IsNib4 : IsNib '4'
IsNib5 : IsNib '5'
IsNib6 : IsNib '6'
IsNib7 : IsNib '7'
IsNib8 : IsNib '8'
IsNib9 : IsNib '9'
IsNibA : IsNib 'a'
IsNibB : IsNib 'b'
IsNibC : IsNib 'c'
IsNibD : IsNib 'd'
IsNibE : IsNib 'e'
IsNibF : IsNib 'f'
data IsHex : String -> Type where
IsHexNil : IsHex "0x"
IsHexApp : IsHex s -> IsNib c0 -> IsNib c1 -> IsHex (s ++ singleton c0 ++ singleton c1)
Hex : Type
Hex = (s : String ** IsHex)
这可能会更有效率,但我正在a lot of issues使用该类型(可能是由于在Idris上没有足够的经验)。
是否可以基于Hex
的第一个定义构建库,但是在将其编译为后端之后,实际使用第二个定义,因为它们明显是同构的?< /强>
答案 0 :(得分:3)
如果我理解你的问题,一个答案是将构造函数重写为常量标识符:H0 = IsNib '0'
等。
在这种情况下,将deriving Enum
添加到您的第一个定义将允许默认toEnum
和fromEnum
在您的第一个编码和0到15之间的数字之间进行转换。然后您可以转换这些使用您选择的库(例如位移和按位以及来自Data.Bits
的{{1}}或intHex
)。您还可以派生Data.ByteString.Builder
的实例,将十六进制数字转换为一个 - Show
Char
和String
。