Merge branch 'ht/newline-before-EOF' into maint
[shapes.git] / examples / features / folds.shape
blobd830bbeb63569d6e03b299c3747346174fa5f04b
1 /** This file is part of Shapes.
2  **
3  ** Shapes is free software: you can redistribute it and/or modify
4  ** it under the terms of the GNU General Public License as published by
5  ** the Free Software Foundation, either version 3 of the License, or
6  ** any later version.
7  **
8  ** Shapes is distributed in the hope that it will be useful,
9  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
10  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  ** GNU General Public License for more details.
12  **
13  ** You should have received a copy of the GNU General Public License
14  ** along with Shapes.  If not, see <http://www.gnu.org/licenses/>.
15  **
16  ** Copyright 2008 Henrik Tidefelt
17  **/
19 ##needs conssupport
21 lst: [range begin:'4 end:'10]
23 /**
24  ** We can measure the length of a list by folding a function that adds one for each element.
25  **/
26 •stdout << `Length: ´ << [lst.foldl (\ p e → '1+p) '0] << "{n}
28 /**
29  ** This is to show the order in which the state is modified when folding with state from left and right.
30  **/
31 [lst.foldsl \ p e •dst → { •dst << e   p } void •stdout]
32 [lst.foldsr \ p e •dst → { •dst << e   p } void •stdout]
33 •stdout << "{n}
35 /**
36  ** To show how the laziness of the cons-pair allows us to define infinite streams, we
37  ** define some basic stream operations...
38  **
39  ** To add two streams is easy.
40  **/
41 stream_add: \ s1 s2 → [cons s1.car+s2.car [stream_add s1.cdr s2.cdr]]
42 /**
43  ** To map infinite streams require some care.  Note that the usual map defined in terms
44  ** of a right fold cannot be used on infinite lists.  Instead, we must define the operation
45  ** from scratch.
46  **/
47 stream_map: \ f lst → [if [null? lst] [list] [cons [f lst.car] [stream_map f lst.cdr]]]
49 /**
50  ** A classic stream example -- the Fibonacci numbers.
51  **/
52 Fib: [cons '0 [cons '1 [stream_add Fib Fib.cdr]]]
54 /**
55  ** We square each number in the stream.
56  **/
57 Fib2: [stream_map (\ x → x*x) Fib]
60 nth: \ lst n → [if n = '0 lst.car [nth lst.cdr n-'1]]
62 •stdout << `A short sequence of Fibonacci numbers:´ << "{n}
64 •stdout << [nth Fib '4] << "{n}
65 •stdout << [nth Fib '5] << "{n}
66 •stdout << [nth Fib '6] << "{n}
68 •stdout << `... and the same sequence squared:´ << "{n}
70 •stdout << [nth Fib2 '4] << "{n}
71 •stdout << [nth Fib2 '5] << "{n}
72 •stdout << [nth Fib2 '6] << "{n}
74 /** Prevent empty output error **/
75 [stroke (0cm,0cm)--(1cm,1cm)]