是否可以为类型定义函数,然后将其编译为它的同构表示?

时间:2018-01-06 02:06:08

标签: haskell functional-programming coq agda idris

假设我为十六进制字符串定义了以下类型:

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的第一个定义构建库,但是在将其编译为后端之后,实际使用第二个定义,因为它们明显是同构的?< /强>

1 个答案:

答案 0 :(得分:3)

如果我理解你的问题,一个答案是将构造函数重写为常量标识符:H0 = IsNib '0'等。

在这种情况下,将deriving Enum添加到您的第一个定义将允许默认toEnumfromEnum在您的第一个编码和0到15之间的数字之间进行转换。然后您可以转换这些使用您选择的库(例如位移和按位以及来自Data.Bits的{​​{1}}或intHex)。您还可以派生Data.ByteString.Builder的实例,将十六进制数字转换为一个 - Show CharString