0

When I check in agda-stdlib/src/Data/List/Base.agda I see that there is no last function but I see in agda-stdlib/src/Data/Vec/Base.agda a function for last.

When I try to use it though I get some type errors that I'm unsure I understand.

This is how I'm trying to call it: last (fromList todos)

where

todos : List Todo

and

record Todo : Set where
  field
    text      : String
    completed : Bool
    id        : ℕ

The error I get is

Data.List.foldr (λ _ → suc) 0 todos != suc _n_31 of type ℕ
when checking that the expression fromList todos has type
Data.Vec.Vec Todo (1 + _n_31)

I'm guessing it has to do with the fact that last has this signature:

last : ∀ {n} → Vec A (1 + n) → A

But I'm confused because when I do C-c C-l on:

last (fromList ?)

I get this goal

?0 : List Todo

which I thought todos satisfied.

What should I change here to make it pass this error? Or is there another way to get the last element of a List?

Thanks!

EDIT

I tried a different route and decided to replace the Vec with List. However I'm getting another error I don't quite understand when I try to do

  Todo.completed (last (todos ∷ʳ record { text = text ; completed = false ; id = 1 }))
≡⟨⟩
  Todo.completed (record { text = text ; completed = false ; id = 1 })
false !=
Todo.completed
(last
 (todos ∷ʳ record { text = text ; completed = false ; id = 1 })
 | Data.Vec.initLast
   (todos ∷ʳ record { text = text ; completed = false ; id = 1 }))
of type Bool
when checking that the inferred type of an application
  false ≡ _y_45
matches the expected type
  Todo.completed
  (last
   (todos ∷ʳ record { text = text ; completed = false ; id = 1 }))
  ≡ false

I'm not sure what the error message is saying here.

EDIT

I tried to simplify the problem down further to

AddNat : ∀ {n : ℕ} → (Vec ℕ n) → (Vec ℕ (1 + n))
AddNat numbers = numbers ∷ʳ 1

AddNatLastAddedElementIsNat :
  ∀ {n : ℕ} (numbers : Vec ℕ (1 + n)) →
    last (AddNat numbers) ≡ 1
AddNatLastAddedElementIsNat numbers =
  begin
    last (AddNat numbers)
  ≡⟨⟩
    last (numbers ∷ʳ 1)
  ≡⟨⟩
    1
  ∎

but I still get a similar error:

1 != (last (numbers ∷ʳ 1) | Data.Vec.initLast (numbers ∷ʳ 1)) of
type ℕ
when checking that the expression 1 ∎ has type
last (numbers ∷ʳ 1) ≡ 1

Why does the last (numbers ∷ʳ 1) show up as type (last (numbers ∷ʳ 1) | Data.Vec.initLast (numbers ∷ʳ 1))? Does | indicate it is a sum type and I would need to pattern match on both cases? Thanks!

fsuna064
  • 195
  • 1
  • 7

1 Answers1

1

The goal in fromList ?0 does have type List Todo, but since fromList ?0 has type Vec _ (length ?0) you'll get an error if the typechecker concludes that there can't be no n such that length ?0 is (definitionally) equal to 1 + n. In your case that happens once you say that ?0 := todos, something like ?0 := x ∷ todos would have worked instead.

Generally a function like last needs to know that the list or vectors is non-empty, an alternative is to define a function that returns Maybe A instead of A though.

Saizan
  • 1,391
  • 8
  • 4