Representing Cyclic Structures as Nested Datatypes. Makoto Hamana

Similar documents
Representing Cyclic Structures as Nested Datatypes

Dependent Polymorphism. Makoto Hamana

Initial Algebra Semantics for Cyclic Sharing Structures. Makoto Hamana

Trees. Solution: type TreeF a t = BinF t a t LeafF 1 point for the right kind; 1 point per constructor.

Lecture 4: Higher Order Functions

The List Datatype. CSc 372. Comparative Programming Languages. 6 : Haskell Lists. Department of Computer Science University of Arizona

From natural numbers to the lambda calculus

Logic - CM0845 Introduction to Haskell

The Algebra of Programming in Haskell

Generalized Iteration and Coiteration for Higher-Order Nested Datatypes

Programming with Math and Logic

Explicit Substitutions and Higher-Order Syntax

Interleaving data and effects

Inductive Types for Free

Introduction to Recursion schemes

GADTs. Wouter Swierstra. Advanced functional programming - Lecture 7. Faculty of Science Information and Computing Sciences

IA014: Advanced Functional Programming

FUNCTIONAL PEARLS The countdown problem

Correct Looping Arrows from Cyclic Terms

GADTs. Wouter Swierstra and Alejandro Serrano. Advanced functional programming - Lecture 7. [Faculty of Science Information and Computing Sciences]

Shared Subtypes. Subtyping Recursive Parameterized Algebraic Data Types

GADTs. Alejandro Serrano. AFP Summer School. [Faculty of Science Information and Computing Sciences]

Exercise 1 (2+2+2 points)

Stream Fusion. Wouter Swierstra 30/11/2010

Universes. Universes for Data. Peter Morris. University of Nottingham. November 12, 2009

Introduction to Co-Induction in Coq

Bringing Functions into the Fold Tom Schrijvers. Leuven Haskell User Group

Generic Programming with Adjunctions

Advanced Functional Programming

Applicative, traversable, foldable

Work-in-progress: Verifying the Glasgow Haskell Compiler Core language

CSCE 314 Programming Languages Functors, Applicatives, and Monads

Applicative, traversable, foldable

JVM ByteCode Interpreter

CS 457/557: Functional Languages

Graphical Untyped Lambda Calculus Interactive Interpreter

Implementing the Opetopes:

Chapter 3: Propositional Languages

INTRODUCTION TO HASKELL

Type Checking and Type Inference

COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen

Homework 3 COSE212, Fall 2018

A Shortcut Fusion Rule for Circular Program Calculation

Typed Racket: Racket with Static Types

Declaring Numbers. Bernd Braßel, Frank Huch and Sebastian Fischer. Department of Computer Science, University of Kiel, Germany

Type families and data kinds

n n Try tutorial on front page to get started! n spring13/ n Stack Overflow!

Functional Pearl: A Smart View on Datatypes

Haskell Programming with Nested Types: A Principled Approach

Monadic Augment and Generalised Short Cut Fusion

Data types à la carte

Overloading, Type Classes, and Algebraic Datatypes

Declarative concurrency. March 3, 2014

CYCLIC DATATYPES MODULO BISIMULATION BASED ON SECOND-ORDER ALGEBRAIC THEORIES

Data types for mcrl2

Standard ML. Data types. ML Datatypes.1

Optimising Functional Programming Languages. Max Bolingbroke, Cambridge University CPRG Lectures 2010

Declarative Programming with Function Patterns

The Typed Racket Guide

Introduction to Functional Programming in Haskell 1 / 56

Processadors de Llenguatge II. Functional Paradigm. Pratt A.7 Robert Harper s SML tutorial (Sec II)

Derivation of a Pattern-Matching Compiler

Programming with Universes, Generically

Harvard School of Engineering and Applied Sciences CS 152: Programming Languages

Structural polymorphism in Generic Haskell

The Zipper. Contents. Henri-Charles Blondeel Pablo Pera. February 22, Introduction 2. 2 Implementation Huet's original Zipper...

Shell CSCE 314 TAMU. Haskell Functions

CS 4110 Programming Languages & Logics. Lecture 28 Recursive Types

Lambda-termide redutseerimine

A Library Writer s Guide to Shortcut Fusion

Many Holes in Hindley-Milner

The essence of dataflow programming. Teooriapäevad Kokel 2,

Programming Languages Third Edition

CS611 Lecture 33 Equirecursive types & Recursive domain equations November 19, 2001

Typed Scheme: Scheme with Static Types

Advances in Programming Languages

Accurate Step Counting

CSCI-GA Scripting Languages

Functional Programming. Overview. Topics. Definition n-th Fibonacci Number. Graph

Faculty of Electrical Engineering, Mathematics, and Computer Science Delft University of Technology

Programming in Omega Part 2. Tim Sheard Portland State University

Streams. CS21b: Structure and Interpretation of Computer Programs Spring Term, 2004

Giving Haskell a Promotion

Talen en Compilers. Jurriaan Hage , period 2. November 13, Department of Information and Computing Sciences Utrecht University

A Small Interpreted Language

Principles of Programming Languages [PLP-2015] Detailed Syllabus

Fusion-powered EDSLs

Functional Languages. Hwansoo Han

Course year Typeclasses and their instances

Theorem Proving Principles, Techniques, Applications Recursion

CSE 3302 Programming Languages Lecture 8: Functional Programming

CS 440: Programming Languages and Translators, Spring 2019 Mon

Work-in-progress: "Verifying" the Glasgow Haskell Compiler Core language

Multi-paradigm Declarative Languages

Foundations For Structured Programming With GADTs

Denotational Semantics. Domain Theory

Programming Languages 3. Definition and Proof by Induction

Running Haskell on the CLR

Functional Programming. Overview. Topics. Recall λ-terms. Examples

CMSC 330: Organization of Programming Languages

Transcription:

Representing Cyclic Structures as Nested Datatypes Makoto Hamana Department of Computer Science, Gunma University, Japan Joint work with Neil Ghani Tarmo Uustalu Varmo Vene U. Nottingham U. Tallinn U. Tartu ToPS, 2006, May 1

Motivation Algebraic datatypes provide a nice way to represent tree-like structures 2

Motivation Algebraic datatypes provide a nice way to represent tree-like structures Lazy languages, e.g. Haskell, allow to build also cyclic structures cycle = 1 : 2 : cycle 2

Motivation Algebraic datatypes provide a nice way to represent tree-like structures Lazy languages, e.g. Haskell, allow to build also cyclic structures cycle = 1 : 2 : cycle or equivalently cycle = fix (\ xs -> 1 : 2 : xs) fix f = x where x = f x 2

Motivation Algebraic datatypes provide a nice way to represent tree-like structures Lazy languages, e.g. Haskell, allow to build also cyclic structures cycle = 1 : 2 : cycle or equivalently cycle = fix (\ xs -> 1 : 2 : xs) fix f = x where x = f x Allows to represent infinite structures in finite memory 2

Motivation Algebraic datatypes provide a nice way to represent tree-like structures Lazy languages, e.g. Haskell, allow to build also cyclic structures cycle = 1 : 2 : cycle or equivalently cycle = fix (\ xs -> 1 : 2 : xs) fix f = x where x = f x Allows to represent infinite structures in finite memory Problem: No support for manipulating cyclic structures 2

Problems on the Usual Approach No support for manipulating cyclic structures E.g. destructing the cyclic structure! map (+1) cycle ==> [2,3,2,3,2,3,2,3,... 3

Problems on the Usual Approach No support for manipulating cyclic structures E.g. destructing the cyclic structure! map (+1) cycle ==> [2,3,2,3,2,3,2,3,... No way to distinguish cyclic / infinite structures 3

Problems on the Usual Approach No support for manipulating cyclic structures E.g. destructing the cyclic structure! map (+1) cycle ==> [2,3,2,3,2,3,2,3,... No way to distinguish cyclic / infinite structures Q. Can we represent cyclic structures inductively? i.e. by algebraic datatypes 3

Problems on the Usual Approach No support for manipulating cyclic structures E.g. destructing the cyclic structure! map (+1) cycle ==> [2,3,2,3,2,3,2,3,... No way to distinguish cyclic / infinite structures Q. Can we represent cyclic structures inductively? i.e. by algebraic datatypes Merit: explicitly manipulate cyclic structures either directly or using generic operations like fold 3

Fegaras-Sheard Approach Cyclic lists as Mixed-variant Datatype by Fegaras, Sheard (POPL 96): data CList = Nil Cons Int CList Rec (CList -> CList) 4

Fegaras-Sheard Approach Cyclic lists as Mixed-variant Datatype by Fegaras, Sheard (POPL 96): data CList = Nil Cons Int CList Rec (CList -> CList) Examples: clist1 = Rec (\ xs -> Cons 1 (Cons 2 xs)) clist2 = Cons 1 (Rec (\ xs -> Cons 2 (Cons 3 xs))) 4

Fegaras-Sheard Approach Cyclic lists as Mixed-variant Datatype by Fegaras, Sheard (POPL 96): data CList = Nil Cons Int CList Rec (CList -> CList) Examples: clist1 = Rec (\ xs -> Cons 1 (Cons 2 xs)) clist2 = Cons 1 (Rec (\ xs -> Cons 2 (Cons 3 xs))) Functions manipulating these representations must unfold Rec-structures. cmap :: (Int -> Int) -> CList -> CList cmap g Nil = Nil cmap g (Cons x xs) = Cons (g x) (cmap g xs) cmap g (Rec f) = cmap g (f (Rec f)) Implicit axiom: Rec f = f (Rec f) 4

Fegaras-Sheard Approach: Problem data CList = Nil Cons Int CList Rec (CList -> CList) Functions manipulating cyclic lists must unwind them 5

Fegaras-Sheard Approach: Problem data CList = Nil Cons Int CList Rec (CList -> CList) Functions manipulating cyclic lists must unwind them There is a blackhole empty = Rec (\ xs -> xs) 5

Fegaras-Sheard Approach: Problem data CList = Nil Cons Int CList Rec (CList -> CList) Functions manipulating cyclic lists must unwind them There is a blackhole empty = Rec (\ xs -> xs) The representation is not unique: clist1 = Rec (\ xs -> Cons 1 (Cons 2 xs)) clist1 = Rec (\ xs -> Rec (\ ys -> Cons 1 (Cons 2 (Rec (\ zs -> xs))))) 5

Fegaras-Sheard Approach: Problem data CList = Nil Cons Int CList Rec (CList -> CList) Functions manipulating cyclic lists must unwind them There is a blackhole empty = Rec (\ xs -> xs) The representation is not unique: clist1 = Rec (\ xs -> Cons 1 (Cons 2 xs)) clist1 = Rec (\ xs -> Rec (\ ys -> Cons 1 (Cons 2 (Rec (\ zs -> xs))))) The semantic category has to be algebraically compact (e.g. CPO) for mixed-variant types to make semantic sense. L = 1 + Z L + (L L) 5

Our Analysis data CList = Nil Cons Int CList Rec (CList -> CList) The same problem has already appeared in Higher-Order Abstract Syntax (HOAS) Induction on function space? 6

Our Analysis data CList = Nil Cons Int CList Rec (CList -> CList) The same problem has already appeared in Higher-Order Abstract Syntax (HOAS) Induction on function space? The same solution was proposed in FP and in semantics Bird and Paterson: De Bruijn Notation as a Nested Datatype, JFP 99 Fiore,Plotkin and Turi: Abstract Syntax and Variable Binding, LICS 99 6

Our Analysis data CList = Nil Cons Int CList Rec (CList -> CList) The same problem has already appeared in Higher-Order Abstract Syntax (HOAS) Induction on function space? The same solution was proposed in FP and in semantics Bird and Paterson: De Bruijn Notation as a Nested Datatype, JFP 99 Fiore,Plotkin and Turi: Abstract Syntax and Variable Binding, LICS 99 Represent lambda terms by a nested datatype Use a kind of de Bruijn notation 6

Cyclic Lists as Nested Datatype Our Proposal: data CList a = Var a Nil RCons Int (CList (Maybe a)) 7

Cyclic Lists as Nested Datatype Our Proposal: data CList a = Var a Nil RCons Int (CList (Maybe a)) data Maybe a = Nothing Just a 7

Cyclic Lists as Nested Datatype Our Proposal: data CList a = Var a Nil RCons Int (CList (Maybe a)) data Maybe a = Nothing Just a Example * RCons 1 (RCons 2 (Var Nothing)) :: CList Void Var a represents a backward pointer to an element in a list. Nothing is the pointer to the first element of a cyclic list. Just Nothing is for the second element, etc. The complete cyclic list has type CList Void (Void is def d by data Void) 7

Examples RCons 1 (RCons 2 (RCons 3 (Var (Just Nothing)))) :: CList Void 8

Examples RCons 1 (RCons 2 (RCons 3 (Var (Just Nothing)))) :: CList Void RCons 1 (RCons 2 (RCons 3 Nil)) :: CList Void Merit: no dangling pointer, i.e. no pointers which point outside the list 8

Examples RCons 1 (RCons 2 (RCons 3 (Var (Just Nothing)))) :: CList Void RCons 1 (RCons 2 (RCons 3 Nil)) :: CList Void Merit: no dangling pointer, i.e. no pointers which point outside the list If type CList Void, it is safe 8

Examples RCons 1 (RCons 2 (RCons 3 (Var (Just Nothing)))) :: CList Void RCons 1 (RCons 2 (RCons 3 Nil)) :: CList Void Merit: no dangling pointer, i.e. no pointers which point outside the list If type CList Void, it is safe E.g. (RCons 3 (Var (Just Nothing))) :: CList (Maybe (Maybe Void)) Different from integer pointer representation 8

Examples RCons 1 (RCons 2 (RCons 3 (Var (Just Nothing)))) :: CList Void RCons 1 (RCons 2 (RCons 3 Nil)) :: CList Void Merit: no dangling pointer, i.e. no pointers which point outside the list If type CList Void, it is safe E.g. (RCons 3 (Var (Just Nothing))) :: CList (Maybe (Maybe Void)) Different from integer pointer representation Unique representation 8

Plan I. Main Part Cyclic lists Cyclic binary trees Semantics II. More Details Generalized fold on cyclic lists General cyclic datatypes de Bruijn levels/indexes and type classes 9

I. Main Part 10

Cyclic Lists as Nested Datatype data CList a = Var a Nil RCons Int (CList (Maybe a)) List algebra structure on Cyclic Lists: cnil :: CList Void cnil = Nil ccons :: Int -> CList Void -> CList Void ccons x xs = RCons x (shift xs) shift :: CList a -> CList (Maybe a) shift (Var z) = Var (Just z) shift Nil = Nil shift (RCons x xs) = RCons x (shift xs) Since pointers denote absolute positions, we need to shift the positions when consing de Bruijn s levels 11

Cyclic Lists as Nested Datatype data CList a = Var a Nil RCons Int (CList (Maybe a)) List algebra structure on Cyclic Lists: cnil :: CList Void cnil = Nil ccons :: Int -> CList Void -> CList Void ccons x xs = RCons x (shift xs) shift :: CList a -> CList (Maybe a) shift (Var z) = Var (Just z) shift Nil = Nil shift (RCons x xs) = RCons x (shift xs) Since pointers denote absolute positions, we need to shift the positions when consing de Bruijn s levels If we use relative positions ( we don t need shifting another problem 11 de Bruijn s indexes)

Cyclic Lists as Nested Datatype Standard fold: cfold :: (forall a. a -> g a) -> (forall a. g a) -> (forall a. Int -> g (Maybe a) -> g a) -> CList a -> g a cfold v n r (Var z) = v z cfold v n r Nil = n cfold v n r (RCons x xs) = r x (cfold v n r xs) Example: newtype K a = K Int csum = cfold (\ x -> K 0) (K 0) (\ i (K j) -> K (i+j)) 12

Cyclic Lists as Nested Datatype Standard fold: cfold :: (forall a. a -> g a) -> (forall a. g a) -> (forall a. Int -> g (Maybe a) -> g a) -> CList a -> g a cfold v n r (Var z) = v z cfold v n r Nil = n cfold v n r (RCons x xs) = r x (cfold v n r xs) Example: newtype K a = K Int csum = cfold (\ x -> K 0) (K 0) (\ i (K j) -> K (i+j)) csum clist1 ==> 3 12

Cyclic Tail 13

Cyclic Tail full cyclic case If the list is full cyclic, append the first element to the last, Otherwise, take a tail & decrease the pointer 14

Cyclic Lists as Nested Datatype List coalgebra structure on cyclic Lists: chead :: CList Void -> Int chead (RCons x _) = x ctail :: CList Void -> CList Void ctail (RCons x xs) = csnoc x xs csnoc y xs appends an element y to the last of xs csnoc :: Int -> CList (Maybe a) -> CList a csnoc y (Var Nothing) = RCons y (Var Nothing) csnoc y (Var (Just z)) = Var z csnoc y Nil = Nil csnoc y (RCons x xs) = RCons x (csnoc y xs) 15

Cyclic Lists as Nested Datatype Interpreting cyclic lists as infinite lists: unwind :: CList Void -> [Int] unwind Nil = [] unwind xs = chead xs : unwind (ctail xs) 16

Cyclic Binary Trees Our Proposal of datatype of cyclic binary trees: data CTree a = VarT a Leaf RBin Int (CTree (Maybe a)) (CTree (Maybe a)) Cyclic binary trees with data at the nodes Each node has an address in top-down manner. All nodes on the same level have the same address. Has only backpointers to form cycles. Pointers to other directions forbidden, hence no sharing. 17

Example RBin 1 (RBin 2 (RBin 3 (VarT Nothing) Leaf) Leaf) (RBin 4 (RBin 5 Leaf Leaf) (RBin 6 Leaf Leaf)) 18

Cyclic Binary Trees Tree algebra structure: cleaf :: CTree Void cleaf = Leaf cbin :: Int -> CTree Void -> CTree Void -> CTree Void cbin x xsl xsr = RBin x (shiftt xsl) (shiftt xsr) shiftt :: CTree a -> CTree (Maybe a) shiftt (VarT z) = VarT (Just z) shiftt Leaf = Leaf shiftt (RBin x xsl xsr) = RBin x (shiftt xsl) (shiftt xsr) 19

Cyclic Children Append 1 to the cyclic point with keeping the right subtree 20

Cyclic Children Taking the left subtree operation: csubl :: CTree Void -> CTree Void csubl (RBin x xsl xsr) = csnocl x xsr xsl csnocl y ys xs appends an element y (with ys) to the leaf of xs csnocl :: Int -> CTree (Maybe a) -> CTree (Maybe a) -> CTree a csnocl y ys (VarT Nothing) = RBin y (VarT Nothing) ys csnocl y ys (VarT (Just z)) = VarT z csnocl y ys Leaf = Leaf csnocl y ys (RBin x xsl xsr) = RBin y (csnocl y ys xsl) (csnocl y ys xsr) where ys = shiftt ys Generalization of ctail 21

Semantics Cyclic Lists data List = Nil Cons Int List data CList a = Var a RNil RCons Int (CList (Maybe a)) cnil = RNil ccons x xs = RCons x (shift xs) chead (RCons x _) = x ctail (RCons x xs) = csnoc x xs 22

Semantics Cyclic Lists List functor F : Set Set, F X = 1 + Z X 23

Semantics Cyclic Lists List functor F : Set Set, F X = 1 + Z X Cyclic list functor G : Set Set Set Set, GA = Id + 1 + Z A(1 + ) 23

Semantics Cyclic Lists List functor F : Set Set, F X = 1 + Z X Cyclic list functor G : Set Set Set Set, GA = Id + 1 + Z A(1 + ) Initial G-algebra GC = C Set C 0 = (CList Void) Set Set 23

Semantics Cyclic Lists List functor F : Set Set, F X = 1 + Z X Cyclic list functor G : Set Set Set Set, GA = Id + 1 + Z A(1 + ) Initial G-algebra GC = C Set C 0 = (CList Void) Set Set finite lists F Z = [nil, cons] Z initial F -alg. in Set F C 0 [cnil, ccons] C0 cpn F C0 finite & infinite lists Z Z xs = pn possible next final F -coalg. F Z 1 + Z Z or head, tail (xs) 23

II. More details Generalized fold General cyclic datatypes de Bruijn levels/indexes 24

Fold on Cyclic Lists Standard fold: cfold :: (forall a. a -> g a) -> (forall a. g a) -> (forall a. Int -> g (Maybe a) -> g a) -> CList a -> g a cfold v n r (Var z) = v z cfold v n r Nil = n cfold v n r (RCons x xs) = r x (cfold v n r xs) This gives cfold (v n c) :: CList a -> T a 25

Fold on Cyclic Lists General recursive definition csnoc y (Var Nothing) = RCons y (Var Nothing) csnoc y (Var (Just z)) = Var z csnoc y Nil = Nil csnoc y (RCons x xs) = RCons x (csnoc y xs) 26

Fold on Cyclic Lists General recursive definition csnoc y (Var Nothing) = RCons y (Var Nothing) csnoc y (Var (Just z)) = Var z csnoc y Nil = Nil csnoc y (RCons x xs) = RCons x (csnoc y xs) Instead: use cfold (v n c) :: CList a -> T a csnoc :: Int -> CList (Maybe a) -> CList a csnoc z xs = cfold var Nil Cons xs where var Nothing = RCons z (Var Nothing) var (Just n) = Var n 26

Fold on Cyclic Lists General recursive definition csnoc y (Var Nothing) = RCons y (Var Nothing) csnoc y (Var (Just z)) = Var z csnoc y Nil = Nil csnoc y (RCons x xs) = RCons x (csnoc y xs) Instead: use cfold (v n c) :: CList a -> T a csnoc :: Int -> CList (Maybe a) -> CList a csnoc z xs = cfold var Nil Cons xs where var Nothing = RCons z (Var Nothing) var (Just n) = Var n But type mismatch! Need: cfold (v n c) :: CList (Maybe a) -> T a 26

Fold on Cyclic Lists Define cfold (v n c) :: CList (Maybe a) -> T a cfold :: (forall a. Maybe a -> f a) -> (forall a. f a) -> (forall a. Int -> f (Maybe a) -> f a) -> CList (Maybe a) -> f a cfold v n c (Var x) = v x cfold v n c Nil = n cfold v n c (Cons x l) = c x (cfold v n c l) 27

Fold on Cyclic Lists Define cfold (v n c) :: CList (Maybe a) -> T a cfold :: (forall a. Maybe a -> f a) -> (forall a. f a) -> (forall a. Int -> f (Maybe a) -> f a) -> CList (Maybe a) -> f a cfold v n c (Var x) = v x cfold v n c Nil = n cfold v n c (Cons x l) = c x (cfold v n c l) The same definition as Standard fold: cfold :: (forall a. a -> g a) -> (forall a. g a) -> (forall a. Int -> g (Maybe a) -> g a) -> CList a -> g a cfold v n r (Var z) = v z cfold v n r Nil = n cfold v n r (RCons x xs) = r x (cfold v n r xs) 27

Fold on Cyclic Lists Generalized fold for nested datatype via a right Kan extension: cefold (v n c) :: CList (M a) -> T a [Bird,Paterson 99][Martin,Gibbons,Bayley 04][Abel,Matthes,Uustalu 05] cefold :: (forall a. Maybe (m a) -> h (Maybe a)) -> (forall a. m a -> t a) -> (forall a. t a) -> (forall a. Int -> g (Maybe a) -> t a) -> CList (m a) -> t a cefold d v n r (Var z) = v z cefold d v n r Nil = n cefold d v n r (RCons x xs) = r x (cefold d v n r (fmap d xs)) d is a distributive law. 28

General Cyclic Datatypes For any given algebraic datatype, we can give its cyclic version. 29

General Cyclic Datatypes For any given algebraic datatype, we can give its cyclic version. Lists F X = 1 + Z X F X = 1 + Z X(1 + ) + Id 29

General Cyclic Datatypes For any given algebraic datatype, we can give its cyclic version. Lists F X = 1 + Z X F X = 1 + Z X(1 + ) + Id Binary trees F X = 1 + Z X X F X = 1 + Z X(1 + ) X(1 + ) + Id 29

General Cyclic Datatypes For any given algebraic datatype, we can give its cyclic version. Lists F X = 1 + Z X F X = 1 + Z X(1 + ) + Id Binary trees F X = 1 + Z X X F X = 1 + Z X(1 + ) X(1 + ) + Id General case easy to guess 29

General Cyclic Datatypes For any given algebraic datatype, we can give its cyclic version. Lists F X = 1 + Z X F X = 1 + Z X(1 + ) + Id Binary trees F X = 1 + Z X X F X = 1 + Z X(1 + ) X(1 + ) + Id General case easy to guess How about general subtree? snoc operation? 29

General Cyclic Datatypes For any given algebraic datatype, we can give its cyclic version. Lists F X = 1 + Z X F X = 1 + Z X(1 + ) + Id Binary trees F X = 1 + Z X X F X = 1 + Z X(1 + ) X(1 + ) + Id General case easy to guess How about general subtree? snoc operation? Derivative of datatype is useful 29

General Cyclic Datatypes Binary trees F X = 1 + Z X X Derivative of datatype (e.g. binary trees, (1 + zx 2 ) = 2zx) F X = ZX + ZX gives a one-hole context [McBride 01] 30

General Cyclic Datatypes Binary trees F X = 1 + Z X X Derivative of datatype (e.g. binary trees, (1 + zx 2 ) = 2zx) F X = ZX + ZX gives a one-hole context [McBride 01] Original snoc for binary trees csnocl :: Int -> CTree (Maybe a) -> CTree (Maybe a) -> CTree a csnocl y ys (VarT Nothing) = RBin y (VarT Nothing) ys... One-hole context is useful: combctx :: F X X F X is the plug-in operation that fills a hole csnocl ctx (VarT Nothing) = combctx ctx (VarT Nothing) 30

Conclusions Generic framework to model cyclic structures 31

Conclusions Generic framework to model cyclic structures Backward pointers no sharing, just cycles 31

Conclusions Generic framework to model cyclic structures Backward pointers no sharing, just cycles Type system guarantees the safety of pointers 31

Conclusions Generic framework to model cyclic structures Backward pointers no sharing, just cycles Type system guarantees the safety of pointers The technique scales up to all polynomial datatypes 31

Conclusions Generic framework to model cyclic structures Backward pointers no sharing, just cycles Type system guarantees the safety of pointers The technique scales up to all polynomial datatypes To do: Extend this to sharing Develop a categorical account of rational and cyclic coinductive types Practical examples Efficiency: regard these as combinators of cyclic structures? Fusion? 31

Conclusions Generic framework to model cyclic structures Backward pointers no sharing, just cycles Type system guarantees the safety of pointers The technique scales up to all polynomial datatypes To do: Extend this to sharing Develop a categorical account of rational and cyclic coinductive types Practical examples Efficiency: regard these as combinators of cyclic structures? Fusion? Paper, slides and programs at: http://www.keim.cs.gunma-u.ac.jp/ hamana/ 31

De Bruijn Indexes Relative pointers rather than absolute ones * Relative: RCons 1 (RCons 2 (Var (Just (Just Nothing)))) 32

De Bruijn Indexes Relative pointers rather than absolute ones * Relative: RCons 1 (RCons 2 (Var (Just (Just Nothing)))) This case: ccons :: Int -> CList Void -> CList Void ccons x xs = RCons x xs 32

De Bruijn Indexes Relative pointers rather than absolute ones * Relative: RCons 1 (RCons 2 (Var (Just (Just Nothing)))) This case: ccons :: Int -> CList Void -> CList Void ccons x xs = RCons x xs -- RCons :: Int -> CList (Maybe a) -> CList a But type mismatch 32

De Bruijn Indexes Second try: ccons :: Int -> CList Void -> CList Void ccons x xs = RCons x (emb xs) emb :: CList a -> CList (Maybe a) emb (Var z) = Var z emb Nil = Nil emb (RCons x xs) = RCons x (emb xs) 33

De Bruijn Indexes Second try: ccons :: Int -> CList Void -> CList Void ccons x xs = RCons x (emb xs) emb :: CList a -> CList (Maybe a) emb (Var z) = Var z emb Nil = Nil emb (RCons x xs) = RCons x (emb xs) ERROR "clists.hs":36 - Type error in explicitly typed binding *** Term : emb *** Type : CList a -> CList a *** Does not match : CList a -> CList (Maybe a) *** Because : unification would give infinite type 33

De Bruijn Indexes Correct Definition class DeBrIdx a where instance DeBrIdx Void where wk :: a -> Maybe a wk _ = undefined instance DeBrIdx a => DeBrIdx (Maybe a) where wk Nothing = Nothing wk (Just x) = Just (wk x) instance Functor CList where fmap f (Var a) = Var (f a) fmap f Nil = Nil fmap f (RCons x xs) = RCons x (fmap (fmap f) xs) emb :: DeBrIdx a => CList a -> CList (Maybe a) emb = fmap wk ccons :: Int -> CList Void -> CList Void ccons x xs = RCons x (emb xs) 34

De Bruijn Indexes Correct Definition emb :: DeBrIdx a => CList a -> CList (Maybe a) ccons :: Int -> CList Void -> CList Void ccons x xs = RCons x (emb xs) Typed program is less efficient than untyped program? Type equality coercion? (suggested by Simon Peyton-Jones at TFP 06) Core language of Haskell: System F with type equality coercion 35