如何在Idris / Agda / Coq中映射Type到Value?

时间:2018-02-02 09:15:17

标签: coq agda idris dependent-type

我试图定义一个名为byteWidth的函数,该函数捕获有关"获取特定原子类型的字节宽度的用法"。

我的第一次试用:

byteWidth : Type -> Int
byteWidth Int = 8
byteWidth Char = 1

Idris编译器抱怨:"当检查byteWidth的左侧时:左侧没有显式类型:Int"

我的第二次试验:

interface BW a where
  byteWidth : a -> Int

implementation BW Int where
  byteWidth _ = 8

implementation BW Char where
  byteWidth _ = 1

在这种情况下,我只能使用byteWidth byteWidth 'a'而不是byteWidth Char

2 个答案:

答案 0 :(得分:10)

您的第二次尝试非常接近有原则的解决方案。正如您所看到的那样,问题在于,在实现a时,您无法将类型BW a作为参数。但是你并不在意,因为你总是可以在以后明确地设置隐式参数。

这给了我们:

interface BW a where
  byteWidth_ : Int

implementation BW Int where
  byteWidth_ = 8

implementation BW Char where
  byteWidth_= 1

然后您可以通过部分应用byteWidth_来恢复您想要的类型:

byteWidth : (a : Type) -> BW a => Int
byteWidth a = byteWidth_ {a}

答案 1 :(得分:1)

在Idris中,你不能模式匹配一​​个类型,并且假设你可以,任何人都不可能枚举所有可能的类型,所以它不可能是完全的。

您需要的唯一额外内容是关于a类型在某个特定集合中的证明,我们将此命题命名为ByteWidthAvailable

data ByteWidthAvailable : Type -> Type where
  IntBWA : ByteWidthAvailable Int
  ChaBWA : ByteWidthAvailable Char

total
byteWidth : (a : Type) -> {auto prf: ByteWidthAvailable a} -> Int
byteWidth _ {prf = IntBWA} = 8
byteWidth _ {prf = ChaBWA} = 1

这里唯一的技巧是Idris提供的auto命令,它有助于在呼叫站点自动生成证据,因此您可以调用byteWidth而不是byteWidth Char而不是byteWidth Char {prf = ChaBWA} {1}}。