The point of ADT syntax is to allow deriving many functions on different data structures automatically. For example, lists and some functions can be defined as:
cons = (x list cons nil -> (cons x (list cons nil)))
nil = (cons nil -> (id nil))
map = (f list cons -> (list (comp cons f)))
head = (list -> (list (a b -> a) nil))
tail = (list cons nil -> (list (h t g -> (g h (t cons))) (const nil) (h t -> t)))
zip_with = (f a b -> ((left a) (right f b)))
left = (foldr (x xs cont -> (cont x xs)) (const []))
right = (f -> (foldr (y ys x cont -> (cons (f x y) (cont ys))) (const (const []))))
length = (flip comp const)
The very same definitions could be written more tersely as just:
List = #{Cons Type * | Nil}
cons = (Ctor 0 List)
nil = (Ctor 1 List)
head = (Getter 0 0 List)
tail = (Getter 0 1 List)
zip_with = (ZipWith List)
length = (Size List)
Where Ctor/Getter/ZipWith/Size are proper derivers. It is possible because all the information you need is there, but it is very hard to come up with those derivers and I currently only have some very bloated derivers for Scott encoded structures, and none for Church encoded structures yet.