简体   繁体   English

阿格达:返回空列表的头尾

[英]Agda: Return head and tail of empty list

I am learning agda and practicing on lists to get a better understanding. 我正在学习agda并在列表上练习以获得更好的理解。 Right now I am trying to write functions for list. 现在我正在尝试为列表编写函数。 I am confused on how to return the head and tail of an empty list. 我很困惑如何返回空列表的头部和尾部。 Here is my code: 这是我的代码:

data list (A : Set) : Set where
[]  : list A
_∷_ : A → list A → list A

Null : {A : Set} → (list A) → Bool
Null [] = true
Null (x ∷ a) = false

tail :  {A : Set} → (list A) → A
tail [] = {!!}
tail (x ∷ []) = x  
tail (x ∷ a) = tail a

head : {A : Set} → (list A) →  A
head [] = {!!}
head (x ∷ a) = x

A work around that I found was that instead of returning the first and last members I return a list containing the first and last members which is as follows: 我找到的一个解决方法是,我返回一个包含第一个和最后一个成员的列表,而不是返回第一个和最后一个成员,如下所示:

tail :  {A : Set} → (list A) → (list A)
tail [] = []
tail (x ∷ []) = x ∷ []  
tail (x ∷ a) = tail a

head : {A : Set} → (list A) → (list A)
head [] = []
head (x ∷ a) = (x ∷ [])

But I am still confused about how to return the head and tail values. 但我仍然对如何返回头部和尾部值感到困惑。 How can I do this? 我怎样才能做到这一点?

PS Not an assignment. PS不是作业。 Miles ahead of this stuff in class 在课堂上提前几英里

In Agda, functions are total: if you have head : {A : Set} -> list A -> A , then it will need to be defined over all lists. 在Agda中,函数是总的:如果你有head : {A : Set} -> list A -> A ,那么它需要在所有列表上定义。 However, for head [] you can't conjure up an element for some arbitrary type A (imagine head ([] : list Void) ...) 但是,对于head []你不能为某个任意类型A想象一个元素(想象head ([] : list Void) ...)

The problem is that your type of head promises too much. 问题是你的head承诺太多了。 It is not, in fact, true that you can return the first element of any list; 事实上,你可以返回任何列表的第一个元素; you can only do it for non-empty lists. 你只能用于非空列表。 So you need to change head to either take a separate proof of non- emptiness , or to take a non-empty list as argument: 所以你需要改变head要么单独证明空虚 ,要么采用非空列表作为参数:

module SeparateProof where
  open import Data.List
  open import Data.Bool
  open import Data.Unit

  head : {A : Set} → (xs : List A) → {{nonEmpty : T (not (null xs))}} → A
  head [] {{nonEmpty = ()}} -- There's no way to pass a proof of non-emptiness for an empty list!
  head (x ∷ xs) = x

module NonEmptyType where
  open import Data.List.NonEmpty hiding (head)

  head : {A : Set} → List⁺ A → A
  head (x ∷ xs) = x -- This is the only pattern matching a List⁺ A!

This is a misnomer, it is last that you wanted not tail, and for the correct tail function, you could just look at drop in Data\\List\\Base.agda of the standard library: 这是一个用词不当,最后你不想尾巴,对于正确的尾部函数,你可以看看标准库的Data \\ List \\ Base.agda中的drop:

drop : ∀ {a} {A : Set a} → ℕ → List A → List A
drop zero    xs       = xs
drop (suc n) []       = []
drop (suc n) (x ∷ xs) = drop n xs
--e.g. drop 1
tail : ∀ {a} {A : Set a} → List A → List A
tail []       = []
tail (x ∷ xs) = xs

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM