adding in the Y combinator stuff
[gitmo/Moose-Autobox.git] / lib / Moose / Autobox / Code.pm
1 package Moose::Autobox::Code;
2 use Moose::Role 'with';
3 use Moose::Autobox;
4
5 our $VERSION = '0.02';
6
7 with 'Moose::Autobox::Ref';
8
9 sub curry {
10     my ($f, @a) = @_;
11     return sub { $f->(@a, @_) }
12 }
13
14 sub rcurry {
15     my ($f, @a) = @_;
16     return sub { $f->(@_, @a) }
17 }
18
19 sub compose {
20         my ($f, $f2, @rest) = @_;
21     return $f if !$f2;
22     return (sub { $f2->($f->(@_)) })->compose(@rest);
23 }
24
25 sub disjoin {
26     my ($f, $f2) = @_;
27     return sub { $f->(@_) || $f2->(@_) }
28 }
29         
30 sub conjoin {
31         my ($f, $f2) = @_;
32         return sub { $f->(@_) && $f2->(@_) }    
33 }
34
35 sub u {
36     my $f = shift;
37     sub { $f->($f, @_) };
38 }
39
40 sub y {
41     my $f = shift;
42     (sub { my $h = shift; sub { $f->(($h->u())->())->(@_) } }->u())->();
43 }
44
45 #sub dump {
46     #my ($self) = @_;
47     #require Data::Dump::Streamer;
48     #return Data::Dump::Streamer::Dump($self)->Out();
49 #}
50
51 1;
52
53 __END__
54
55 =pod
56
57 =head1 NAME 
58
59 Moose::Autobox::Code - the Code role
60
61 =head1 SYNOPOSIS
62
63   use Moose::Autobox;
64   
65   my $adder = sub { $_[0] + $_[1] };
66   my $add_2 = $adder->curry(2);
67   
68   $add_2->(2); # returns 4
69   
70   # create a recursive subroutine 
71   # using the Y combinator
72   *factorial = sub {
73       my $f = shift;
74       sub {
75           my $n = shift;
76           return 1 if $n < 2;
77           return $n * $f->($n - 1);
78       }
79   }->y;
80   
81   factorial(10) # returns 3628800
82   
83
84 =head1 DESCRIPTION
85
86 This is a role to describe operations on the Code type. 
87
88 =head1 METHODS
89
90 =over 4
91
92 =item B<curry (@values)>
93
94 =item B<rcurry (@values)>
95
96 =item B<conjoin (\&sub)>
97
98 =item B<disjoin (\&sub)>
99
100 =item B<compose (@subs)>
101
102 This will take a list of C<@subs> and compose them all into a single 
103 subroutine where the output of one sub will be the input of another. 
104
105 =item B<y>
106
107 This implements the Y combinator.
108
109 =item B<u>
110
111 This implements the U combinator.
112
113 =back
114
115 =over 4
116
117 =item B<meta>
118
119 =back
120
121 =head1 SEE ALSO
122
123 =over 4
124
125 =item L<http://en.wikipedia.org/wiki/Fixed_point_combinator>
126
127 =back
128
129 =head1 BUGS
130
131 All complex software has bugs lurking in it, and this module is no 
132 exception. If you find a bug please either email me, or add the bug
133 to cpan-RT.
134
135 =head1 AUTHOR
136
137 Stevan Little E<lt>stevan@iinteractive.comE<gt>
138
139 =head1 COPYRIGHT AND LICENSE
140
141 Copyright 2006 by Infinity Interactive, Inc.
142
143 L<http://www.iinteractive.com>
144
145 This library is free software; you can redistribute it and/or modify
146 it under the same terms as Perl itself.
147
148 =cut