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