(xs: Vect n elem) & # 8594; Vect (n * 2) elem

The book Type Driven Development with Idris presents this exercise:

Define a possible method that matches the signature:

two : (xs : Vect n elem) -> Vect (n * 2) elem

I tried:

two : (xs : Vect n elem) -> Vect (n * 2) elem
two xs = xs ++ xs

But I got the following error:

*One> :r
Type checking ./One.idr
One.idr:9:5:When checking right hand side of two:
Type mismatch between
        Vect (n + n) elem (Type of xs ++ xs)
and
        Vect (mult n 2) elem (Expected type)

Specifically:
        Type mismatch between
                plus n n
        and
                mult n 2
Holes: Hw1.two

If I have a vector of size N and I need a vector of size N * 2, adding it to myself seems reasonable.

What am I doing wrong?

+4
source share
1 answer

Short answer

Change the type signature to two : (xs : Vect n elem) -> Vect (n + n) elem.

If you really need it

Access to a Vect (n * 2) elemlittle harder. Here:

two' : Vect n elem -> Vect (n * 2) elem
two' {n} xs = rewrite multCommutative n 2 in rewrite plusZeroRightNeutral n in xs ++ xs

, , , . n + n mult n 2 , . (mult n 2 - , n * 2 .)

mult :

*kevinmeredith> :printdef mult
mult : Nat -> Nat -> Nat
mult 0 right = 0
mult (S left) right = plus right (mult left right)

. two n, mult . multCommutative :

*kevinmeredith> :t multCommutative 
multCommutative : (left : Nat) ->
                  (right : Nat) -> left * right = right * left

- rewrite, two'. ( :t replace REPL, , ). rewrite foo in bar foo - a = b, bar , a b s. two' , Vect (n * 2) Vect (2 * n). mult. mult 2 i.e. S (S Z) n, plus n (mult (S Z) n, plus n (plus n (mult Z n)), plus n (plus n Z). , :

two' : Vect n elem -> Vect (n * 2) elem
two' {n} xs = rewrite multCommutative n 2 in ?aaa

:

*kevinmeredith> :t aaa
  elem : Type
  n : Nat
  xs : Vect n elem
  _rewrite_rule : plus n (plus n 0) = mult n 2
--------------------------------------
aaa : Vect (plus n (plus n 0)) elem

plus n Z , plus , , mult. plusZeroRightNeutral :

*kevinmeredith> :t plusZeroRightNeutral 
plusZeroRightNeutral : (left : Nat) -> left + 0 = left

rewrite.

:search . , - .

*kevinmeredith> :s (n : Nat) -> n + 0 = n
= Prelude.Nat.multOneLeftNeutral : (right : Nat) ->
                                   fromInteger 1 * right = right


= Prelude.Nat.plusZeroRightNeutral : (left : Nat) ->
                                     left + fromInteger 0 = left


*kevinmeredith> :s (n, m : Nat) -> n * m = m * n
= Prelude.Nat.multCommutative : (left : Nat) ->
                                (right : Nat) -> left * right = right * left

( 0.9.20.1)

+12

Source: https://habr.com/ru/post/1616827/


All Articles