Created
January 25, 2012 18:29
-
-
Save palladin/1677761 to your computer and use it in GitHub Desktop.
Bananas in F#
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.125 | |
type ListF<'a, 'b> = Empty | Cons of 'a * 'b | |
type List<'a> = InL of ListF<'a, List<'a>> with | |
member self.Out() = let (InL x) = self in x | |
type PeanoF<'b> = Zero | Suc of 'b | |
type Peano = InP of PeanoF<Peano> with | |
member self.Out() = let (InP x) = self in x | |
let inline out x = (^MF : (member Out : unit -> ^F) (x)) | |
// Binary Functor | |
type BiFunctor = F with | |
static member ($) (F, x:ListF<_, _>) = | |
fun f g -> | |
match x with | |
| Empty -> Empty | |
| Cons (x, xs) -> Cons (f x, g xs) | |
static member ($) (F, x:PeanoF<_>) = | |
fun f g -> | |
match x with | |
| Zero -> Zero | |
| Suc x -> Suc (g x) | |
let inline bmap f g x = (F $ x) f g | |
// (|φ|) | |
let inline cata phi x = | |
let rec cata' x = | |
phi (bmap id cata' (out x)) | |
cata' x | |
// Example | |
let threeP = InP (Suc (InP (Suc (InP (Suc (InP Zero)))))) | |
let threeL = InL (Cons (1, (InL (Cons (2, (InL (Cons (3, (InL Empty))))))))) | |
cata (fun x -> match x with Suc n -> n + 1 | Zero -> 0) threeP // 3 | |
cata (fun x -> match x with Cons (x, l) -> x :: l| Empty -> []) threeL // [1; 2; 3] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment