我试图定义一个名为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
。
答案 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}}。