检查Vector的长度是否相等

时间:2017-02-27 02:40:33

标签: idris

Type-Driven Development with Idris获得以下内容:

import Data.Vect

data EqNat : (num1 : Nat) -> (num2 : Nat) -> Type where
  Same : (num : Nat) -> EqNat num num                               

sameS : (eq : EqNat k j) -> EqNat (S k) (S j)
sameS (Same n) = Same (S n)

checkEqNat : (num1 : Nat) -> (num2 : Nat) -> Maybe (EqNat num1 num2)
checkEqNat Z     Z     = Just $ Same Z
checkEqNat Z     (S k) = Nothing
checkEqNat (S k) Z     = Nothing
checkEqNat (S k) (S j) = case checkEqNat k j of
                           Just eq => Just $ sameS eq
                           Nothing => Nothing

exactLength : (len : Nat) -> (input : Vect m a) -> Maybe (Vect len a)
exactLength {m} len input = case (checkEqNat m len) of 
                              Just (Same m) => Just input
                              Nothing       => Nothing

如果我用Just (Same m)替换最后一个函数的Just eq,编译器会抱怨:

*Lecture> :r
Type checking ./Lecture.idr
Lecture.idr:19:75:
When checking right hand side of Main.case block in exactLength at Lecture.idr:18:34 with expected type
        Maybe (Vect len a)

When checking argument x to constructor Prelude.Maybe.Just:
        Type mismatch between
                Vect m a (Type of input)
        and
                Vect len a (Expected type)

        Specifically:
                Type mismatch between
                        m
                and
                        len
Holes: Main.exactLength

Just (Same m)(即工作代码)如何提供exactLength的{​​{1}}和len相等的“证据”?

2 个答案:

答案 0 :(得分:2)

在与伊德里斯合作时,我觉得有用的是在你不确定某些事情而不是解决问题时增加漏洞。就像在Just ...分支中添加一个洞来查看那里发生了什么:

exactLength : (len : Nat) -> (input : Vect m a) -> Maybe (Vect len a)
exactLength {m} len input = case (checkEqNat m len) of
                        Just (Same m) => ?hole
                        Nothing => Nothing

然后在查看类型检查结果时将(Same m)更改为eq并返回。在eq案例中,它是这样的:

- + Main.hole [P]
 `--          a : Type
              m : Nat
            len : Nat
             eq : EqNat m len
          input : Vect m a
     --------------------------------
      Main.hole : Maybe (Vect len a)

(Same m)案例中,它是这样的:

- + Main.hole_1 [P]
 `--            m : Nat
                a : Type
            input : Vect m a
     --------------------------------
      Main.hole_1 : Maybe (Vect m a)

所以eq属于EqNat m len类型,没有人知道它是否居住,而Same m(或Same len)绝对是居民证明m和len是平等的。

答案 1 :(得分:1)

当你从

开始
exactLength : (len : Nat) -> (input : Vect m a) -> Maybe (Vect len a)
exactLength {m} len input  with (_)
  exactLength {m} len input  | with_pat = ?_rhs

逐渐扩展缺失的链接,直至到达

exactLength : (len : Nat) -> (input : Vect m a) -> Maybe (Vect len a)
exactLength {m} len input  with (checkEqNat m len)
  exactLength {m = m} len input  | Nothing = Nothing
  exactLength {m = len} len input  | (Just (Same len)) = Just input

你可以看到idris如何从checkEqNat m len返回Just (Same ...)然后推断出{m = len}的事实中得出。仅仅写Just eq的AFAIK并不能证明eq确实有人居住。