在Agda中编写构造函数作为函数的更好方法

时间:2014-11-23 19:41:39

标签: agda

我有一个清单

data List (X : Set) : Set where
  <>   : List X
  _,_  : X -> List X -> List X

平等的定义

data _==_ {l}{X : Set l}(x : X) : X -> Set l where
  refl : x == x

和同意

cong : forall {k l}{X : Set k}{Y : Set l}(f : X -> Y){x y} -> x == y -> f x == f y
cong f refl = refl

我想证明

propFlatten2 : {X : Set } ( xs0 : List X ) (x : X)  (xs1 : List X) (xs2 : List X)
              -> ( xs0 ++ x , xs1 ) ++ xs2  ==  xs0 ++ (x , xs1 ++ xs2 )
propFlatten2 <> x xs1 xs2 = refl
propFlatten2 (x , xs0) x₁ xs1 xs2 =   cong (λ l -> x , l) {!!}

除了通过最后一行中的lambda之外,还有更好的方法直接使用构造函数_,_吗?

1 个答案:

答案 0 :(得分:2)

Agda没有任何特殊的语法来部分应用运算符。但是,您可以使用通常的前缀版本中的运算符:

x + y = _+_ x y

当你需要部分应用最左边的参数时,这很方便:

_+_ 1 = λ x → 1 + x

当您需要从右侧部分应用参数时,您的选项会受到更多限制。正如评论中所提到的,您可以使用其中一个便利功能,例如flip(在Function中找到):

flip f x y = f y x  -- Type omitted for brevity.

然后只需flip _+_的参数:

flip _+_ 1 = λ x → x + 1

有时您会找到运营商,其唯一目的是使代码更好一些。我能想到的最好的例子可能是Data.Product.,_。当您编写从属对(Data.Product.Σ)时,有时可以自动填充对的第一部分。而不是写:

_ , x

你可以写:

, x

很难说当写一个像上面这样的专业运算符时实际上是值得的;如果你的唯一用例是同意使用它,我会坚持使用lambda,因为它非常清楚发生了什么。