如何在Idris中为Vect写出正确的类型签名?

时间:2017-08-13 16:19:27

标签: dependent-type idris purely-functional

最近我一直在探索伊德里斯的依赖类型。但是,我克服了一个非常烦人的问题,在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类型?

1 个答案:

答案 0 :(得分:2)

我不确定我的解释是否正确,但是以下类型检查:

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和{ {1}}是一样的。