如何在 Idris 中为 Vect 编写正确的类型签名?
How to write correct type signature for Vect in Idris?
最近我一直在探索 Idris 中的依赖类型。但是,我克服了一个非常烦人的问题,在 Idris 中,我应该使用类型签名启动我的程序。所以问题是,如何在 Idris 中编写简洁的类型签名?
例如,
get_member : (store : Vect n String) -> (idx : List (Fin n)) -> (m : Nat ** Vect m (Nat, String))
get_member store idx = Vect.mapMaybe maybe_member (Vect.fromList idx)
where
maybe_member : (x : Fin n) -> Maybe (Nat, String)
-- The below line should be type corrected
-- maybe_member x = Just (Data.Fin.finToNat x, Vect.index x store)
如果我注释最后一行,编译将对上面的函数进行类型检查,
但如果我将最后一行作为表达式,编译会报错。
When checking right hand side of VecSort.get_member, maybe_member with expected type
Maybe (Nat, String)
When checking an application of function Data.Vect.index:
Type mismatch between
Vect n1 String (Type of store)
and
Vect n String (Expected type)
Specifically:
Type mismatch between
n1
and
n
但我用 lambda 函数来做,
get_member : (store : Vect n String) -> (idx : List (Fin n)) -> (m : Nat ** Vect m (Nat, String))
get_member store idx = Vect.mapMaybe (\x => Just (Data.Fin.finToNat x, Vect.index x store)) (Vect.fromList idx)
也会进行类型检查。
所以问题是,我应该如何在类型签名中定义具有正确长度的 Vect 类型?
我不确定我的解释是否正确,但以下类型检查:
get_member : (store : Vect n String) -> (idx : List (Fin n)) -> (m : Nat ** Vect m (Nat, String))
get_member store idx {n} = Vect.mapMaybe (maybe_member) (Vect.fromList idx)
where
maybe_member : (x : Fin n) -> Maybe (Nat, String)
maybe_member x = Just (Data.Fin.finToNat x, Vect.index x store)
不同之处在于您将隐式参数 n
放入您的范围。 {n}
和 x: Fin x
指的是同一个 n
。如果不在你的范围内拉隐式 n
,idris 不能假设两个 n
确实相同,它会抱怨错误消息,它不知道 n1
和 n
是一样的。
最近我一直在探索 Idris 中的依赖类型。但是,我克服了一个非常烦人的问题,在 Idris 中,我应该使用类型签名启动我的程序。所以问题是,如何在 Idris 中编写简洁的类型签名?
例如,
get_member : (store : Vect n String) -> (idx : List (Fin n)) -> (m : Nat ** Vect m (Nat, String))
get_member store idx = Vect.mapMaybe maybe_member (Vect.fromList idx)
where
maybe_member : (x : Fin n) -> Maybe (Nat, String)
-- The below line should be type corrected
-- maybe_member x = Just (Data.Fin.finToNat x, Vect.index x store)
如果我注释最后一行,编译将对上面的函数进行类型检查, 但如果我将最后一行作为表达式,编译会报错。
When checking right hand side of VecSort.get_member, maybe_member with expected type
Maybe (Nat, String)
When checking an application of function Data.Vect.index:
Type mismatch between
Vect n1 String (Type of store)
and
Vect n String (Expected type)
Specifically:
Type mismatch between
n1
and
n
但我用 lambda 函数来做,
get_member : (store : Vect n String) -> (idx : List (Fin n)) -> (m : Nat ** Vect m (Nat, String))
get_member store idx = Vect.mapMaybe (\x => Just (Data.Fin.finToNat x, Vect.index x store)) (Vect.fromList idx)
也会进行类型检查。
所以问题是,我应该如何在类型签名中定义具有正确长度的 Vect 类型?
我不确定我的解释是否正确,但以下类型检查:
get_member : (store : Vect n String) -> (idx : List (Fin n)) -> (m : Nat ** Vect m (Nat, String))
get_member store idx {n} = Vect.mapMaybe (maybe_member) (Vect.fromList idx)
where
maybe_member : (x : Fin n) -> Maybe (Nat, String)
maybe_member x = Just (Data.Fin.finToNat x, Vect.index x store)
不同之处在于您将隐式参数 n
放入您的范围。 {n}
和 x: Fin x
指的是同一个 n
。如果不在你的范围内拉隐式 n
,idris 不能假设两个 n
确实相同,它会抱怨错误消息,它不知道 n1
和 n
是一样的。