重写方法:Vect(S(S(n(m + m))))a-> Vect(S(n +(S m)))a

时间:2018-08-19 16:17:38

标签: idris

我被伊德里斯卡住了(再次叹息)。我正在第10章的Idris书中进行类型驱动开发的合并排序练习。

import Data.Vect
import Data.Vect.Views

sort2 : Ord a => (l: a) -> (r: a) -> (a, a)
sort2 l r = if l <= r then (l, r) else (r, l)

needHelp :  Vect (S (S (n + m))) a -> Vect (S (plus n (S m))) a
needHelp {n=(S n)} {m=(S m)} (x :: xs) = ?help

vectMerge : Ord a => Vect n a -> Vect m a -> Vect (n + m) a
vectMerge [] ys = ys
vectMerge {n} xs [] = rewrite plusZeroRightNeutral n in xs
vectMerge {n=(S n)} {m=(S m)} (x :: xs) (y :: ys) =
  let (f, s) = sort2 x y in
  needHelp (f :: s :: (vectMerge xs ys))

我已经隔离了needHelp函数,因此您可以看到我想要实现的重写。我尝试过:

vectMerge : Ord a => Vect n a -> Vect m a -> Vect (n + m) a
vectMerge [] ys = ys
vectMerge {n} xs [] = rewrite plusZeroRightNeutral n in xs
vectMerge {n=(S n)} {m=(S m)} (x :: xs) (y :: ys) =
  let (f, s) = sort2 x y in
  let tail = (rewrite plusSuccRightSucc n m in s :: vectMerge xs ys) in
  f :: tail

但是Idris抱怨:

When checking right hand side of Main.case block in vectMerge with expected type
        Vect (S (plus n (S m))) a

rewriting S (plus n m) to plus n (S m) did not change type letty

我不明白为什么这行不通。非常感谢。

1 个答案:

答案 0 :(得分:1)

rewrite与您的当前目标有关,而不是与您用来解决目标的术语有关(我试图在this answer中进行说明)

所以,这是一个可能的解决方案:

import Data.Vect

sort2 : Ord a => (l: a) -> (r: a) -> (a, a)
sort2 l r = if l <= r then (l, r) else (r, l)

vectMerge : Ord a => Vect n a -> Vect m a -> Vect (n + m) a
vectMerge [] ys = ys
vectMerge {n} xs [] = rewrite plusZeroRightNeutral n in xs
vectMerge {n=(S n)} {m=(S m)} (x :: xs) (y :: ys) =
  let (f, s) = sort2 x y in
  rewrite sym $ plusSuccRightSucc n m in
  (f :: s :: (vectMerge xs ys))
sym中的

sym $ plusSuccRightSucc n m颠倒了rewrite的方向。