从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
相等的“证据”?
答案 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
确实有人居住。