Rebuild docs
This commit is contained in:
@@ -10,44 +10,43 @@ several generic specializations.
|
||||
|
||||
::
|
||||
|
||||
[if] [then] [rec1] [rec2] genrec
|
||||
---------------------------------------------------------------------
|
||||
[if] [then] [rec1 [[if] [then] [rec1] [rec2] genrec] rec2] ifte
|
||||
[if] [then] [rec1] [rec2] genrec
|
||||
---------------------------------------------------------------------
|
||||
[if] [then] [rec1 [[if] [then] [rec1] [rec2] genrec] rec2] ifte
|
||||
|
||||
From "Recursion Theory and Joy" (j05cmp.html) by Manfred von Thun:
|
||||
From “Recursion Theory and Joy” (j05cmp.html) by Manfred von Thun:
|
||||
|
||||
"The genrec combinator takes four program parameters in addition to
|
||||
whatever data parameters it needs. Fourth from the top is an
|
||||
if-part, followed by a then-part. If the if-part yields true, then
|
||||
the then-part is executed and the combinator terminates. The other
|
||||
two parameters are the rec1-part and the rec2-part. If the if-part
|
||||
yields false, the rec1-part is executed. Following that the four
|
||||
program parameters and the combinator are again pushed onto the
|
||||
stack bundled up in a quoted form. Then the rec2-part is executed,
|
||||
where it will find the bundled form. Typically it will then execute
|
||||
the bundled form, either with i or with app2, or some other
|
||||
combinator."
|
||||
“The genrec combinator takes four program parameters in addition to
|
||||
whatever data parameters it needs. Fourth from the top is an if-part,
|
||||
followed by a then-part. If the if-part yields true, then the
|
||||
then-part is executed and the combinator terminates. The other two
|
||||
parameters are the rec1-part and the rec2-part. If the if-part yields
|
||||
false, the rec1-part is executed. Following that the four program
|
||||
parameters and the combinator are again pushed onto the stack bundled
|
||||
up in a quoted form. Then the rec2-part is executed, where it will
|
||||
find the bundled form. Typically it will then execute the bundled
|
||||
form, either with i or with app2, or some other combinator.”
|
||||
|
||||
Designing Recursive Functions
|
||||
-----------------------------
|
||||
|
||||
The way to design one of these is to fix your base case and test and
|
||||
then treat ``R1`` and ``R2`` as an else-part "sandwiching" a quotation
|
||||
then treat ``R1`` and ``R2`` as an else-part “sandwiching” a quotation
|
||||
of the whole function.
|
||||
|
||||
For example, given a (general recursive) function ``F``:
|
||||
|
||||
::
|
||||
|
||||
F == [I] [T] [R1] [R2] genrec
|
||||
== [I] [T] [R1 [F] R2] ifte
|
||||
F == [I] [T] [R1] [R2] genrec
|
||||
== [I] [T] [R1 [F] R2] ifte
|
||||
|
||||
If the ``[I]`` predicate is false you must derive ``R1`` and ``R2``
|
||||
from:
|
||||
|
||||
::
|
||||
|
||||
... R1 [F] R2
|
||||
... R1 [F] R2
|
||||
|
||||
Set the stack arguments in front and figure out what ``R1`` and ``R2``
|
||||
have to do to apply the quoted ``[F]`` in the proper way.
|
||||
@@ -59,9 +58,9 @@ Primitive recursive functions are those where ``R2 == i``.
|
||||
|
||||
::
|
||||
|
||||
P == [I] [T] [R] primrec
|
||||
== [I] [T] [R [P] i] ifte
|
||||
== [I] [T] [R P] ifte
|
||||
P == [I] [T] [R] primrec
|
||||
== [I] [T] [R [P] i] ifte
|
||||
== [I] [T] [R P] ifte
|
||||
|
||||
`Hylomorphism <https://en.wikipedia.org/wiki/Hylomorphism_%28computer_science%29>`__
|
||||
------------------------------------------------------------------------------------
|
||||
@@ -75,8 +74,8 @@ is a recursive function ``H :: A -> C`` that converts a value of type
|
||||
- A combiner ``F :: (B, C) -> C``
|
||||
- A predicate ``P :: A -> Bool`` to detect the base case
|
||||
- A base case value ``c :: C``
|
||||
- Recursive calls (zero or more); it has a "call stack in the form of a
|
||||
cons list".
|
||||
- Recursive calls (zero or more); it has a “call stack in the form of a
|
||||
cons list”.
|
||||
|
||||
It may be helpful to see this function implemented in imperative Python
|
||||
code.
|
||||
@@ -96,12 +95,12 @@ code.
|
||||
|
||||
return H
|
||||
|
||||
Cf. `"Bananas, Lenses, & Barbed
|
||||
Wire" <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.125>`__
|
||||
Cf. `“Bananas, Lenses, & Barbed
|
||||
Wire” <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.125>`__
|
||||
|
||||
Note that during evaluation of ``H()`` the intermediate ``b`` values are
|
||||
stored in the Python call stack. This is what is meant by "call stack in
|
||||
the form of a cons list".
|
||||
stored in the Python call stack. This is what is meant by “call stack in
|
||||
the form of a cons list”.
|
||||
|
||||
Hylomorphism in Joy
|
||||
-------------------
|
||||
@@ -111,7 +110,7 @@ hylomorphism combinator ``H`` from constituent parts.
|
||||
|
||||
::
|
||||
|
||||
H == [P] c [G] [F] hylomorphism
|
||||
H == [P] c [G] [F] hylomorphism
|
||||
|
||||
The function ``H`` is recursive, so we start with ``ifte`` and set the
|
||||
else-part to some function ``J`` that will contain a quoted copy of
|
||||
@@ -120,37 +119,37 @@ with the base case value ``c``.)
|
||||
|
||||
::
|
||||
|
||||
H == [P] [pop c] [J] ifte
|
||||
H == [P] [pop c] [J] ifte
|
||||
|
||||
The else-part ``J`` gets just the argument ``a`` on the stack.
|
||||
|
||||
::
|
||||
|
||||
a J
|
||||
a G The first thing to do is use the generator G
|
||||
aa b which produces b and a new aa
|
||||
aa b [H] dip we recur with H on the new aa
|
||||
aa H b F and run F on the result.
|
||||
a J
|
||||
a G The first thing to do is use the generator G
|
||||
aa b which produces b and a new aa
|
||||
aa b [H] dip we recur with H on the new aa
|
||||
aa H b F and run F on the result.
|
||||
|
||||
This gives us a definition for ``J``.
|
||||
|
||||
::
|
||||
|
||||
J == G [H] dip F
|
||||
J == G [H] dip F
|
||||
|
||||
Plug it in and convert to genrec.
|
||||
|
||||
::
|
||||
|
||||
H == [P] [pop c] [G [H] dip F] ifte
|
||||
H == [P] [pop c] [G] [dip F] genrec
|
||||
H == [P] [pop c] [G [H] dip F] ifte
|
||||
H == [P] [pop c] [G] [dip F] genrec
|
||||
|
||||
This is the form of a hylomorphism in Joy, which nicely illustrates that
|
||||
it is a simple specialization of the general recursion combinator.
|
||||
|
||||
::
|
||||
|
||||
H == [P] c [G] [F] hylomorphism == [P] [pop c] [G] [dip F] genrec
|
||||
H == [P] c [G] [F] hylomorphism == [P] [pop c] [G] [dip F] genrec
|
||||
|
||||
Derivation of ``hylomorphism`` combinator
|
||||
-----------------------------------------
|
||||
@@ -160,9 +159,9 @@ arguments out of the pieces given to the ``hylomorphism`` combinator.
|
||||
|
||||
::
|
||||
|
||||
[P] c [G] [F] hylomorphism
|
||||
------------------------------------------
|
||||
[P] [pop c] [G] [dip F] genrec
|
||||
[P] c [G] [F] hylomorphism
|
||||
------------------------------------------
|
||||
[P] [pop c] [G] [dip F] genrec
|
||||
|
||||
Working in reverse:
|
||||
|
||||
@@ -174,17 +173,17 @@ So:
|
||||
|
||||
::
|
||||
|
||||
H == [P] [pop c] [G] [dip F] genrec
|
||||
[P] [c] [pop] swoncat [G] [F] [dip] swoncat genrec
|
||||
[P] c unit [pop] swoncat [G] [F] [dip] swoncat genrec
|
||||
[P] c [G] [F] [unit [pop] swoncat] dipd [dip] swoncat genrec
|
||||
H == [P] [pop c] [G] [dip F] genrec
|
||||
[P] [c] [pop] swoncat [G] [F] [dip] swoncat genrec
|
||||
[P] c unit [pop] swoncat [G] [F] [dip] swoncat genrec
|
||||
[P] c [G] [F] [unit [pop] swoncat] dipd [dip] swoncat genrec
|
||||
|
||||
At this point all of the arguments (givens) to the hylomorphism are to
|
||||
the left so we have a definition for ``hylomorphism``:
|
||||
|
||||
::
|
||||
|
||||
hylomorphism == [unit [pop] swoncat] dipd [dip] swoncat genrec
|
||||
hylomorphism == [unit [pop] swoncat] dipd [dip] swoncat genrec
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
@@ -193,7 +192,7 @@ the left so we have a definition for ``hylomorphism``:
|
||||
Example: Finding `Triangular Numbers <https://en.wikipedia.org/wiki/Triangular_number>`__
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Let's write a function that, given a positive integer, returns the sum
|
||||
Let’s write a function that, given a positive integer, returns the sum
|
||||
of all positive integers less than that one. (In this case the types
|
||||
``A``, ``B`` and ``C`` are all ``int``.)
|
||||
|
||||
@@ -208,7 +207,7 @@ To sum a range of integers from 0 to *n* - 1:
|
||||
|
||||
define('triangular_number == [1 <=] 0 [-- dup] [+] hylomorphism')
|
||||
|
||||
Let's try it:
|
||||
Let’s try it:
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
@@ -236,30 +235,30 @@ Four Specializations
|
||||
There are at least four kinds of recursive combinator, depending on two
|
||||
choices. The first choice is whether the combiner function ``F`` should
|
||||
be evaluated during the recursion or pushed into the pending expression
|
||||
to be "collapsed" at the end. The second choice is whether the combiner
|
||||
to be “collapsed” at the end. The second choice is whether the combiner
|
||||
needs to operate on the current value of the datastructure or the
|
||||
generator's output, in other words, whether ``F`` or ``G`` should run
|
||||
generator’s output, in other words, whether ``F`` or ``G`` should run
|
||||
first in the recursive branch.
|
||||
|
||||
::
|
||||
|
||||
H1 == [P] [pop c] [G ] [dip F] genrec
|
||||
H2 == c swap [P] [pop] [G [F] dip ] [i] genrec
|
||||
H3 == [P] [pop c] [ [G] dupdip ] [dip F] genrec
|
||||
H4 == c swap [P] [pop] [ [F] dupdip G] [i] genrec
|
||||
H1 == [P] [pop c] [G ] [dip F] genrec
|
||||
H2 == c swap [P] [pop] [G [F] dip ] [i] genrec
|
||||
H3 == [P] [pop c] [ [G] dupdip ] [dip F] genrec
|
||||
H4 == c swap [P] [pop] [ [F] dupdip G] [i] genrec
|
||||
|
||||
The working of the generator function ``G`` differs slightly for each.
|
||||
Consider the recursive branches:
|
||||
|
||||
::
|
||||
|
||||
... a G [H1] dip F w/ a G == a′ b
|
||||
... a G [H1] dip F w/ a G == a′ b
|
||||
|
||||
... c a G [F] dip H2 a G == b a′
|
||||
... c a G [F] dip H2 a G == b a′
|
||||
|
||||
... a [G] dupdip [H3] dip F a G == a′
|
||||
... a [G] dupdip [H3] dip F a G == a′
|
||||
|
||||
... c a [F] dupdip G H4 a G == a′
|
||||
... c a [F] dupdip G H4 a G == a′
|
||||
|
||||
The following four sections illustrate how these work, omitting the
|
||||
predicate evaluation.
|
||||
@@ -269,31 +268,31 @@ predicate evaluation.
|
||||
|
||||
::
|
||||
|
||||
H1 == [P] [pop c] [G] [dip F] genrec
|
||||
H1 == [P] [pop c] [G] [dip F] genrec
|
||||
|
||||
Iterate n times.
|
||||
|
||||
::
|
||||
|
||||
... a G [H1] dip F
|
||||
... a′ b [H1] dip F
|
||||
... a′ H1 b F
|
||||
... a′ G [H1] dip F b F
|
||||
... a″ b′ [H1] dip F b F
|
||||
... a″ H1 b′ F b F
|
||||
... a″ G [H1] dip F b′ F b F
|
||||
... a‴ b″ [H1] dip F b′ F b F
|
||||
... a‴ H1 b″ F b′ F b F
|
||||
... a‴ pop c b″ F b′ F b F
|
||||
... c b″ F b′ F b F
|
||||
... d b′ F b F
|
||||
... d′ b F
|
||||
... d″
|
||||
... a G [H1] dip F
|
||||
... a′ b [H1] dip F
|
||||
... a′ H1 b F
|
||||
... a′ G [H1] dip F b F
|
||||
... a″ b′ [H1] dip F b F
|
||||
... a″ H1 b′ F b F
|
||||
... a″ G [H1] dip F b′ F b F
|
||||
... a‴ b″ [H1] dip F b′ F b F
|
||||
... a‴ H1 b″ F b′ F b F
|
||||
... a‴ pop c b″ F b′ F b F
|
||||
... c b″ F b′ F b F
|
||||
... d b′ F b F
|
||||
... d′ b F
|
||||
... d″
|
||||
|
||||
This form builds up a pending expression (continuation) that contains
|
||||
the intermediate results along with the pending combiner functions. When
|
||||
the base case is reached the last term is replaced by the identity value
|
||||
``c`` and the continuation "collapses" into the final result using the
|
||||
``c`` and the continuation “collapses” into the final result using the
|
||||
combiner ``F``.
|
||||
|
||||
``H2``
|
||||
@@ -307,53 +306,53 @@ reverse order.
|
||||
|
||||
::
|
||||
|
||||
H2 == c swap [P] [pop] [G [F] dip] primrec
|
||||
H2 == c swap [P] [pop] [G [F] dip] primrec
|
||||
|
||||
... c a G [F] dip H2
|
||||
... c b a′ [F] dip H2
|
||||
... c b F a′ H2
|
||||
... d a′ H2
|
||||
... d a′ G [F] dip H2
|
||||
... d b′ a″ [F] dip H2
|
||||
... d b′ F a″ H2
|
||||
... d′ a″ H2
|
||||
... d′ a″ G [F] dip H2
|
||||
... d′ b″ a‴ [F] dip H2
|
||||
... d′ b″ F a‴ H2
|
||||
... d″ a‴ H2
|
||||
... d″ a‴ pop
|
||||
... d″
|
||||
... c a G [F] dip H2
|
||||
... c b a′ [F] dip H2
|
||||
... c b F a′ H2
|
||||
... d a′ H2
|
||||
... d a′ G [F] dip H2
|
||||
... d b′ a″ [F] dip H2
|
||||
... d b′ F a″ H2
|
||||
... d′ a″ H2
|
||||
... d′ a″ G [F] dip H2
|
||||
... d′ b″ a‴ [F] dip H2
|
||||
... d′ b″ F a‴ H2
|
||||
... d″ a‴ H2
|
||||
... d″ a‴ pop
|
||||
... d″
|
||||
|
||||
``H3``
|
||||
~~~~~~
|
||||
|
||||
If you examine the traces above you'll see that the combiner ``F`` only
|
||||
gets to operate on the results of ``G``, it never "sees" the first value
|
||||
If you examine the traces above you’ll see that the combiner ``F`` only
|
||||
gets to operate on the results of ``G``, it never “sees” the first value
|
||||
``a``. If the combiner and the generator both need to work on the
|
||||
current value then ``dup`` must be used, and the generator must produce
|
||||
one item instead of two (the b is instead the duplicate of a.)
|
||||
|
||||
::
|
||||
|
||||
H3 == [P] [pop c] [[G] dupdip] [dip F] genrec
|
||||
H3 == [P] [pop c] [[G] dupdip] [dip F] genrec
|
||||
|
||||
... a [G] dupdip [H3] dip F
|
||||
... a G a [H3] dip F
|
||||
... a′ a [H3] dip F
|
||||
... a′ H3 a F
|
||||
... a′ [G] dupdip [H3] dip F a F
|
||||
... a′ G a′ [H3] dip F a F
|
||||
... a″ a′ [H3] dip F a F
|
||||
... a″ H3 a′ F a F
|
||||
... a″ [G] dupdip [H3] dip F a′ F a F
|
||||
... a″ G a″ [H3] dip F a′ F a F
|
||||
... a‴ a″ [H3] dip F a′ F a F
|
||||
... a‴ H3 a″ F a′ F a F
|
||||
... a‴ pop c a″ F a′ F a F
|
||||
... c a″ F a′ F a F
|
||||
... d a′ F a F
|
||||
... d′ a F
|
||||
... d″
|
||||
... a [G] dupdip [H3] dip F
|
||||
... a G a [H3] dip F
|
||||
... a′ a [H3] dip F
|
||||
... a′ H3 a F
|
||||
... a′ [G] dupdip [H3] dip F a F
|
||||
... a′ G a′ [H3] dip F a F
|
||||
... a″ a′ [H3] dip F a F
|
||||
... a″ H3 a′ F a F
|
||||
... a″ [G] dupdip [H3] dip F a′ F a F
|
||||
... a″ G a″ [H3] dip F a′ F a F
|
||||
... a‴ a″ [H3] dip F a′ F a F
|
||||
... a‴ H3 a″ F a′ F a F
|
||||
... a‴ pop c a″ F a′ F a F
|
||||
... c a″ F a′ F a F
|
||||
... d a′ F a F
|
||||
... d′ a F
|
||||
... d″
|
||||
|
||||
``H4``
|
||||
~~~~~~
|
||||
@@ -364,22 +363,22 @@ the form:
|
||||
|
||||
::
|
||||
|
||||
H4 == c swap [P] [pop] [[F] dupdip G] primrec
|
||||
H4 == c swap [P] [pop] [[F] dupdip G] primrec
|
||||
|
||||
... c a [F] dupdip G H4
|
||||
... c a F a G H4
|
||||
... d a G H4
|
||||
... d a′ H4
|
||||
... d a′ [F] dupdip G H4
|
||||
... d a′ F a′ G H4
|
||||
... d′ a′ G H4
|
||||
... d′ a″ H4
|
||||
... d′ a″ [F] dupdip G H4
|
||||
... d′ a″ F a″ G H4
|
||||
... d″ a″ G H4
|
||||
... d″ a‴ H4
|
||||
... d″ a‴ pop
|
||||
... d″
|
||||
... c a [F] dupdip G H4
|
||||
... c a F a G H4
|
||||
... d a G H4
|
||||
... d a′ H4
|
||||
... d a′ [F] dupdip G H4
|
||||
... d a′ F a′ G H4
|
||||
... d′ a′ G H4
|
||||
... d′ a″ H4
|
||||
... d′ a″ [F] dupdip G H4
|
||||
... d′ a″ F a″ G H4
|
||||
... d″ a″ G H4
|
||||
... d″ a‴ H4
|
||||
... d″ a‴ pop
|
||||
... d″
|
||||
|
||||
Anamorphism
|
||||
-----------
|
||||
@@ -390,13 +389,10 @@ values.
|
||||
|
||||
::
|
||||
|
||||
A == [P] [] [G] [swons] hylomorphism
|
||||
A == [P] [] [G] [swons] hylomorphism
|
||||
|
||||
``range`` et. al.
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
An example of an anamorphism is the ``range`` function which generates
|
||||
the list of integers from 0 to *n* - 1 given *n*.
|
||||
``range`` et. al. An example of an anamorphism is the ``range`` function which generates the list of integers from 0 to *n* - 1 given *n*.
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Each of the above variations can be used to make four slightly different
|
||||
``range`` functions.
|
||||
@@ -406,8 +402,8 @@ Each of the above variations can be used to make four slightly different
|
||||
|
||||
::
|
||||
|
||||
H1 == [P] [pop c] [G] [dip F] genrec
|
||||
== [0 <=] [pop []] [-- dup] [dip swons] genrec
|
||||
H1 == [P] [pop c] [G] [dip F] genrec
|
||||
== [0 <=] [pop []] [-- dup] [dip swons] genrec
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
@@ -428,8 +424,8 @@ Each of the above variations can be used to make four slightly different
|
||||
|
||||
::
|
||||
|
||||
H2 == c swap [P] [pop] [G [F] dip] primrec
|
||||
== [] swap [0 <=] [pop] [-- dup [swons] dip] primrec
|
||||
H2 == c swap [P] [pop] [G [F] dip] primrec
|
||||
== [] swap [0 <=] [pop] [-- dup [swons] dip] primrec
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
@@ -450,8 +446,8 @@ Each of the above variations can be used to make four slightly different
|
||||
|
||||
::
|
||||
|
||||
H3 == [P] [pop c] [[G] dupdip] [dip F] genrec
|
||||
== [0 <=] [pop []] [[--] dupdip] [dip swons] genrec
|
||||
H3 == [P] [pop c] [[G] dupdip] [dip F] genrec
|
||||
== [0 <=] [pop []] [[--] dupdip] [dip swons] genrec
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
@@ -472,8 +468,8 @@ Each of the above variations can be used to make four slightly different
|
||||
|
||||
::
|
||||
|
||||
H4 == c swap [P] [pop] [[F] dupdip G ] primrec
|
||||
== [] swap [0 <=] [pop] [[swons] dupdip --] primrec
|
||||
H4 == c swap [P] [pop] [[F] dupdip G ] primrec
|
||||
== [] swap [0 <=] [pop] [[swons] dupdip --] primrec
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
@@ -503,7 +499,7 @@ and makes some new value.
|
||||
|
||||
::
|
||||
|
||||
C == [not] c [uncons swap] [F] hylomorphism
|
||||
C == [not] c [uncons swap] [F] hylomorphism
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
@@ -513,7 +509,7 @@ An example of a catamorphism is the sum function.
|
||||
|
||||
::
|
||||
|
||||
sum == [not] 0 [swuncons] [+] hylomorphism
|
||||
sum == [not] 0 [swuncons] [+] hylomorphism
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
@@ -585,16 +581,16 @@ For the Factorial function:
|
||||
|
||||
::
|
||||
|
||||
H4 == c swap [P] [pop] [[F] dupdip G] primrec
|
||||
H4 == c swap [P] [pop] [[F] dupdip G] primrec
|
||||
|
||||
With:
|
||||
|
||||
::
|
||||
|
||||
c == 1
|
||||
F == *
|
||||
G == --
|
||||
P == 1 <=
|
||||
c == 1
|
||||
F == *
|
||||
G == --
|
||||
P == 1 <=
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
@@ -613,31 +609,31 @@ With:
|
||||
Example: ``tails``
|
||||
------------------
|
||||
|
||||
An example of a paramorphism for lists given in the `"Bananas..."
|
||||
An example of a paramorphism for lists given in the `“Bananas…”
|
||||
paper <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.125>`__
|
||||
is ``tails`` which returns the list of "tails" of a list.
|
||||
is ``tails`` which returns the list of “tails” of a list.
|
||||
|
||||
::
|
||||
|
||||
[1 2 3] tails
|
||||
--------------------
|
||||
[[] [3] [2 3]]
|
||||
[1 2 3] tails
|
||||
--------------------
|
||||
[[] [3] [2 3]]
|
||||
|
||||
We can build as we go, and we want ``F`` to run after ``G``, so we use
|
||||
pattern ``H2``:
|
||||
|
||||
::
|
||||
|
||||
H2 == c swap [P] [pop] [G [F] dip] primrec
|
||||
H2 == c swap [P] [pop] [G [F] dip] primrec
|
||||
|
||||
We would use:
|
||||
|
||||
::
|
||||
|
||||
c == []
|
||||
F == swons
|
||||
G == rest dup
|
||||
P == not
|
||||
c == []
|
||||
F == swons
|
||||
G == rest dup
|
||||
P == not
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
@@ -656,39 +652,39 @@ We would use:
|
||||
Conclusion: Patterns of Recursion
|
||||
---------------------------------
|
||||
|
||||
Our story so far...
|
||||
Our story so far…
|
||||
|
||||
Hylo-, Ana-, Cata-
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
H == [P ] [pop c ] [G ] [dip F ] genrec
|
||||
A == [P ] [pop []] [G ] [dip swap cons] genrec
|
||||
C == [not] [pop c ] [uncons swap] [dip F ] genrec
|
||||
H == [P ] [pop c ] [G ] [dip F ] genrec
|
||||
A == [P ] [pop []] [G ] [dip swap cons] genrec
|
||||
C == [not] [pop c ] [uncons swap] [dip F ] genrec
|
||||
|
||||
Para-, ?-, ?-
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
P == c swap [P ] [pop] [[F ] dupdip G ] primrec
|
||||
? == [] swap [P ] [pop] [[swap cons] dupdip G ] primrec
|
||||
? == c swap [not] [pop] [[F ] dupdip uncons swap] primrec
|
||||
P == c swap [P ] [pop] [[F ] dupdip G ] primrec
|
||||
? == [] swap [P ] [pop] [[swap cons] dupdip G ] primrec
|
||||
? == c swap [not] [pop] [[F ] dupdip uncons swap] primrec
|
||||
|
||||
Appendix: Fun with Symbols
|
||||
--------------------------
|
||||
|
||||
::
|
||||
|
||||
|[ (c, F), (G, P) ]| == (|c, F|) • [(G, P)]
|
||||
|[ (c, F), (G, P) ]| == (|c, F|) • [(G, P)]
|
||||
|
||||
`"Bananas, Lenses, & Barbed
|
||||
Wire" <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.125>`__
|
||||
`“Bananas, Lenses, & Barbed
|
||||
Wire” <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.125>`__
|
||||
|
||||
::
|
||||
|
||||
(|...|) [(...)] [<...>]
|
||||
(|...|) [(...)] [<...>]
|
||||
|
||||
I think they are having slightly too much fun with the symbols. However,
|
||||
"Too much is always better than not enough."
|
||||
“Too much is always better than not enough.”
|
||||
|
||||
Reference in New Issue
Block a user