如何将Idris/Agda/Coq中的类型映射为值?

如何将Idris/Agda/Coq中的类型映射为值?,coq,agda,idris,dependent-type,Coq,Agda,Idris,Dependent Type,我试图定义一个名为byteWidth的函数,它捕获了关于“获取特定原子类型的字节宽度”的用法 我的第一次审判: byteWidth : Type -> Int byteWidth Int = 8 byteWidth Char = 1 Idris编译器抱怨:“当检查字节宽度的左侧时:左侧没有显式类型:Int” 我的第二次审判: interface BW a where byteWidth : a -> Int implementation BW Int where by

我试图定义一个名为
byteWidth
的函数,它捕获了关于“获取特定原子类型的字节宽度”的用法


我的第一次审判:

byteWidth : Type -> Int
byteWidth Int = 8
byteWidth Char = 1
Idris编译器抱怨:“当检查字节宽度的左侧时:左侧没有显式类型: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
在Idris中,你不能模式匹配一个类型,并且假设你可以,任何人都不可能枚举所有可能的类型,所以它不能是总数

你需要做的唯一额外的事情是证明
a
类型在某个特定集合中,我们将这个命题命名为
字节宽度可用

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 Char
一样调用
byteWidth Char
而不是
byteWidth Char{prf=ChaBWA}
您的第二次尝试非常接近原则解决方案。正如您所观察到的,问题是在实现
BW a
时,不能将类型
a
作为参数。但是你不在乎,因为你可以在以后明确地设置一个隐式参数

这给了我们:

interface BW a where
  byteWidth_ : Int

implementation BW Int where
  byteWidth_ = 8

implementation BW Char where
  byteWidth_= 1
然后,您可以通过部分应用
字节宽度
恢复所需的类型,如下所示:

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

这是可行的,但太棘手了。。。我仍然认为我的解决方案更好…您的解决方案使用了
{auto pr:}
,这是一种反模式感谢您指出这一点,但我无法理解为什么它是一种反模式,更多的细节或示例,或一些参考?这是一种让系统随机猜测一些证据(达到一定深度)的方法而且因为它太容易使用,人们正在滥用它,而不是证明他们的问题是可判定的,或者使用更具原则性的搜索策略(例如,这个问题本质上是关于类型类的)。类型类本质上是解决问题的一种开放方式:当您意识到需要时,您可以添加新实例。使用单例+自动方法,只有控制原始库的人才能添加新案例。它是反模块的。