recursion-schemes 5.2.2.1 → 5.2.2.2
raw patch · 5 files changed
+479/−5 lines, 5 filesdep ~template-haskell
Dependency ranges changed: template-haskell
Files
- CHANGELOG.markdown +3/−0
- README.markdown +7/−0
- docs/flowchart.svg +458/−0
- recursion-schemes.cabal +4/−4
- src/Data/Functor/Foldable/TH.hs +7/−1
CHANGELOG.markdown view
@@ -1,3 +1,6 @@+## 5.2.2.2++* Support GHC-9.0 and GHC-9.2 ## 5.2.2.1
README.markdown view
@@ -155,6 +155,13 @@ The [Data.Functor.Foldable](https://hackage.haskell.org/package/recursion-schemes/docs/Data-Functor-Foldable.html) module provides many more. +## Flowchart for choosing a recursion-scheme+++++In addition to the choices described by the flowchart, you can always choose to use a refold.+ ## Contributing Contributions and [bug reports](https://github.com/ekmett/recursion-schemes/issues/new) are welcome!
+ docs/flowchart.svg view
@@ -0,0 +1,458 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">+<!-- Generated by graphviz version 2.43.0 (0)+ -->+<!-- Title: %3 Pages: 1 -->+<svg width="1672pt" height="1063pt"+ viewBox="0.00 0.00 1672.12 1063.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">+<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 1059)">+<title>%3</title>+<polygon fill="white" stroke="transparent" points="-4,4 -4,-1059 1668.12,-1059 1668.12,4 -4,4"/>+<g id="clust1" class="cluster">+<title>cluster_beginner</title>+<polygon fill="none" stroke="transparent" points="575,-557 575,-863 1169,-863 1169,-557 575,-557"/>+</g>+<g id="clust2" class="cluster">+<title>cluster_expert</title>+<polygon fill="none" stroke="transparent" points="8,-557 8,-716 567,-716 567,-557 8,-557"/>+</g>+<!-- decision1 -->+<g id="node1" class="node">+<title>decision1</title>+<polygon fill="none" stroke="black" points="723,-855 583,-817 723,-779 863,-817 723,-855"/>+<text text-anchor="middle" x="723" y="-820.8" font-family="Times,serif" font-size="14.00">Is your input</text>+<text text-anchor="middle" x="723" y="-805.8" font-family="Times,serif" font-size="14.00">a recursive type?</text>+</g>+<!-- decision1_1 -->+<g id="node2" class="node">+<title>decision1_1</title>+<polygon fill="none" stroke="black" points="1021,-728 881,-690 1021,-652 1161,-690 1021,-728"/>+<text text-anchor="middle" x="1021" y="-693.8" font-family="Times,serif" font-size="14.00">Is your output</text>+<text text-anchor="middle" x="1021" y="-678.8" font-family="Times,serif" font-size="14.00">a recursive type?</text>+</g>+<!-- decision1->decision1_1 -->+<g id="edge10" class="edge">+<title>decision1->decision1_1</title>+<path fill="none" stroke="black" d="M776.62,-793.51C827.52,-772.16 904.04,-740.06 957.87,-717.48"/>+<polygon fill="black" stroke="black" points="959.44,-720.62 967.31,-713.52 956.73,-714.16 959.44,-720.62"/>+<text text-anchor="middle" x="901.5" y="-749.8" font-family="Times,serif" font-size="14.00">yes</text>+</g>+<!-- decision1_2 -->+<g id="node3" class="node">+<title>decision1_2</title>+<polygon fill="none" stroke="black" points="723,-728 583,-690 723,-652 863,-690 723,-728"/>+<text text-anchor="middle" x="723" y="-693.8" font-family="Times,serif" font-size="14.00">Is your output</text>+<text text-anchor="middle" x="723" y="-678.8" font-family="Times,serif" font-size="14.00">a recursive type?</text>+</g>+<!-- decision1->decision1_2 -->+<g id="edge11" class="edge">+<title>decision1->decision1_2</title>+<path fill="none" stroke="black" d="M723,-778.83C723,-766.1 723,-751.68 723,-738.26"/>+<polygon fill="black" stroke="black" points="726.5,-738.24 723,-728.24 719.5,-738.24 726.5,-738.24"/>+<text text-anchor="middle" x="732" y="-749.8" font-family="Times,serif" font-size="14.00">no</text>+</g>+<!-- decision1_1_no -->+<g id="node6" class="node">+<title>decision1_1_no</title>+<ellipse fill="none" stroke="transparent" cx="1002" cy="-583" rx="27" ry="18"/>+<text text-anchor="middle" x="1002" y="-579.3" font-family="Times,serif" font-size="14.00">No</text>+</g>+<!-- decision1_1->decision1_1_no -->+<g id="edge4" class="edge">+<title>decision1_1->decision1_1_no</title>+<path fill="none" stroke="black" d="M1014.57,-653.45C1011.36,-635.72 1007.63,-615.1 1005.07,-600.96"/>+</g>+<!-- choose_either -->+<g id="node7" class="node">+<title>choose_either</title>+<ellipse fill="none" stroke="black" cx="872" cy="-583" rx="65.79" ry="18"/>+<text text-anchor="middle" x="872" y="-579.3" font-family="Times,serif" font-size="14.00">I feel lucky!</text>+</g>+<!-- decision1_1->choose_either -->+<g id="edge12" class="edge">+<title>decision1_1->choose_either</title>+<path fill="none" stroke="black" d="M983.02,-662.23C958.24,-644.78 926.32,-622.28 903.07,-605.89"/>+<polygon fill="black" stroke="black" points="904.8,-602.83 894.61,-599.93 900.77,-608.56 904.8,-602.83"/>+<text text-anchor="middle" x="954.5" y="-622.8" font-family="Times,serif" font-size="14.00">yes</text>+</g>+<!-- decision1_2_yes -->+<g id="node4" class="node">+<title>decision1_2_yes</title>+<ellipse fill="none" stroke="transparent" cx="723" cy="-583" rx="27" ry="18"/>+<text text-anchor="middle" x="723" y="-579.3" font-family="Times,serif" font-size="14.00">Yes</text>+</g>+<!-- decision1_2->decision1_2_yes -->+<g id="edge5" class="edge">+<title>decision1_2->decision1_2_yes</title>+<path fill="none" stroke="black" d="M723,-651.98C723,-634.62 723,-614.78 723,-601.04"/>+</g>+<!-- decision1_2_no -->+<g id="node5" class="node">+<title>decision1_2_no</title>+<ellipse fill="none" stroke="transparent" cx="651" cy="-583" rx="27" ry="18"/>+<text text-anchor="middle" x="651" y="-579.3" font-family="Times,serif" font-size="14.00">No</text>+</g>+<!-- decision1_2->decision1_2_no -->+<g id="edge6" class="edge">+<title>decision1_2->decision1_2_no</title>+<path fill="none" stroke="black" d="M701.59,-657.78C688.49,-638.68 672.29,-615.05 661.81,-599.76"/>+</g>+<!-- start_unfolds -->+<g id="node9" class="node">+<title>start_unfolds</title>+<ellipse fill="none" stroke="black" cx="689" cy="-472" rx="79.09" ry="18"/>+<text text-anchor="middle" x="689" y="-468.3" font-family="Times,serif" font-size="14.00">Use an unfold!</text>+</g>+<!-- decision1_2_yes->start_unfolds -->+<g id="edge8" class="edge">+<title>decision1_2_yes->start_unfolds</title>+<path fill="none" stroke="black" d="M717.69,-564.97C712.26,-547.55 703.74,-520.24 697.39,-499.9"/>+<polygon fill="black" stroke="black" points="700.71,-498.78 694.39,-490.27 694.02,-500.86 700.71,-498.78"/>+</g>+<!-- start_refolds -->+<g id="node10" class="node">+<title>start_refolds</title>+<ellipse fill="none" stroke="black" cx="520" cy="-472" rx="71.49" ry="18"/>+<text text-anchor="middle" x="520" y="-468.3" font-family="Times,serif" font-size="14.00">Use a refold!</text>+</g>+<!-- decision1_2_no->start_refolds -->+<g id="edge9" class="edge">+<title>decision1_2_no->start_refolds</title>+<path fill="none" stroke="black" d="M634.67,-568.42C612.92,-550.31 574.11,-518.02 547.72,-496.07"/>+<polygon fill="black" stroke="black" points="549.89,-493.32 539.97,-489.61 545.41,-498.7 549.89,-493.32"/>+</g>+<!-- start_folds -->+<g id="node8" class="node">+<title>start_folds</title>+<ellipse fill="none" stroke="black" cx="937" cy="-472" rx="61.99" ry="18"/>+<text text-anchor="middle" x="937" y="-468.3" font-family="Times,serif" font-size="14.00">Use a fold!</text>+</g>+<!-- decision1_1_no->start_folds -->+<g id="edge7" class="edge">+<title>decision1_1_no->start_folds</title>+<path fill="none" stroke="black" d="M992.41,-565.92C981.83,-548.17 964.65,-519.37 952.23,-498.53"/>+<polygon fill="black" stroke="black" points="955.19,-496.66 947.06,-489.87 949.17,-500.25 955.19,-496.66"/>+</g>+<!-- choose_either->start_folds -->+<g id="edge19" class="edge">+<title>choose_either->start_folds</title>+<path fill="none" stroke="black" d="M882.16,-564.97C892.75,-547.21 909.47,-519.17 921.67,-498.71"/>+<polygon fill="black" stroke="black" points="924.8,-500.29 926.92,-489.91 918.79,-496.71 924.8,-500.29"/>+</g>+<!-- choose_either->start_unfolds -->+<g id="edge20" class="edge">+<title>choose_either->start_unfolds</title>+<path fill="none" stroke="black" d="M845.78,-566.38C813.98,-547.44 760.24,-515.43 724.69,-494.26"/>+<polygon fill="black" stroke="black" points="726.45,-491.23 716.07,-489.12 722.87,-497.25 726.45,-491.23"/>+</g>+<!-- choose_either->start_refolds -->+<!-- fold1 -->+<g id="node13" class="node">+<title>fold1</title>+<polygon fill="none" stroke="black" points="1018,-417 799,-379 1018,-341 1237,-379 1018,-417"/>+<text text-anchor="middle" x="1018" y="-382.8" font-family="Times,serif" font-size="14.00">Do you only combine results</text>+<text text-anchor="middle" x="1018" y="-367.8" font-family="Times,serif" font-size="14.00">from recursive calls?</text>+</g>+<!-- start_folds->fold1 -->+<g id="edge22" class="edge">+<title>start_folds->fold1</title>+<path fill="none" stroke="black" d="M951.86,-454.31C960.56,-444.54 971.94,-431.75 982.8,-419.55"/>+<polygon fill="black" stroke="black" points="985.43,-421.85 989.47,-412.06 980.2,-417.2 985.43,-421.85"/>+</g>+<!-- unfold1 -->+<g id="node17" class="node">+<title>unfold1</title>+<polygon fill="none" stroke="black" points="545,-417 309,-379 545,-341 781,-379 545,-417"/>+<text text-anchor="middle" x="545" y="-382.8" font-family="Times,serif" font-size="14.00">Do you only generate subtrees</text>+<text text-anchor="middle" x="545" y="-367.8" font-family="Times,serif" font-size="14.00">by making recursive calls?</text>+</g>+<!-- start_unfolds->unfold1 -->+<g id="edge31" class="edge">+<title>start_unfolds->unfold1</title>+<path fill="none" stroke="black" d="M663.59,-454.94C646.05,-443.86 622.06,-428.7 600.24,-414.91"/>+<polygon fill="black" stroke="black" points="602.01,-411.88 591.68,-409.5 598.27,-417.8 602.01,-411.88"/>+</g>+<!-- decision0 -->+<g id="node11" class="node">+<title>decision0</title>+<polygon fill="none" stroke="black" points="505,-982 267,-944 505,-906 743,-944 505,-982"/>+<text text-anchor="middle" x="505" y="-947.8" font-family="Times,serif" font-size="14.00">Do you know which shape your</text>+<text text-anchor="middle" x="505" y="-932.8" font-family="Times,serif" font-size="14.00">function's recursion will have?</text>+</g>+<!-- decision0->decision1 -->+<g id="edge2" class="edge">+<title>decision0->decision1</title>+<path fill="none" stroke="black" d="M555.56,-914.01C589.85,-894.35 635.1,-868.4 669.92,-848.44"/>+<polygon fill="black" stroke="black" points="672.05,-851.25 678.98,-843.24 668.57,-845.18 672.05,-851.25"/>+<text text-anchor="middle" x="636" y="-876.8" font-family="Times,serif" font-size="14.00">no</text>+</g>+<!-- expert_decision1 -->+<g id="node12" class="node">+<title>expert_decision1</title>+<polygon fill="none" stroke="black" points="336,-708 196.08,-690 336,-672 475.92,-690 336,-708"/>+<text text-anchor="middle" x="336" y="-686.3" font-family="Times,serif" font-size="14.00">What is the shape?</text>+</g>+<!-- decision0->expert_decision1 -->+<g id="edge3" class="edge">+<title>decision0->expert_decision1</title>+<path fill="none" stroke="black" d="M482.56,-909.54C447.96,-857.95 382.43,-760.24 352.12,-715.04"/>+<polygon fill="black" stroke="black" points="355.03,-713.09 346.55,-706.73 349.21,-716.99 355.03,-713.09"/>+<text text-anchor="middle" x="462.5" y="-813.3" font-family="Times,serif" font-size="14.00">yes</text>+</g>+<!-- same_as_input_type -->+<g id="node29" class="node">+<title>same_as_input_type</title>+<ellipse fill="none" stroke="transparent" cx="458" cy="-583" rx="100.98" ry="18"/>+<text text-anchor="middle" x="458" y="-579.3" font-family="Times,serif" font-size="14.00">Same as input type</text>+</g>+<!-- expert_decision1->same_as_input_type -->+<g id="edge13" class="edge">+<title>expert_decision1->same_as_input_type</title>+<path fill="none" stroke="black" d="M353.22,-674.18C375.68,-654.85 414.89,-621.1 438.45,-600.83"/>+</g>+<!-- same_as_output_type -->+<g id="node30" class="node">+<title>same_as_output_type</title>+<ellipse fill="none" stroke="transparent" cx="233" cy="-583" rx="106.68" ry="18"/>+<text text-anchor="middle" x="233" y="-579.3" font-family="Times,serif" font-size="14.00">Same as output type</text>+</g>+<!-- expert_decision1->same_as_output_type -->+<g id="edge15" class="edge">+<title>expert_decision1->same_as_output_type</title>+<path fill="none" stroke="black" d="M320.8,-673.51C301.78,-654.11 269.3,-621 249.63,-600.95"/>+</g>+<!-- neither -->+<g id="node31" class="node">+<title>neither</title>+<ellipse fill="none" stroke="transparent" cx="62" cy="-583" rx="46.29" ry="18"/>+<text text-anchor="middle" x="62" y="-579.3" font-family="Times,serif" font-size="14.00">Neither</text>+</g>+<!-- expert_decision1->neither -->+<g id="edge17" class="edge">+<title>expert_decision1->neither</title>+<path fill="none" stroke="black" d="M302.68,-676.23C249.48,-655.84 146.06,-616.21 93.82,-596.19"/>+</g>+<!-- fold2 -->+<g id="node14" class="node">+<title>fold2</title>+<polygon fill="none" stroke="black" points="973,-290 810,-252 973,-214 1136,-252 973,-290"/>+<text text-anchor="middle" x="973" y="-255.8" font-family="Times,serif" font-size="14.00">Only from</text>+<text text-anchor="middle" x="973" y="-240.8" font-family="Times,serif" font-size="14.00">immediate children?</text>+</g>+<!-- fold1->fold2 -->+<g id="edge23" class="edge">+<title>fold1->fold2</title>+<path fill="none" stroke="black" d="M1005.35,-342.85C1000.23,-328.63 994.26,-312.06 988.86,-297.05"/>+<polygon fill="black" stroke="black" points="992.08,-295.68 985.4,-287.46 985.5,-298.05 992.08,-295.68"/>+<text text-anchor="middle" x="1010.5" y="-311.8" font-family="Times,serif" font-size="14.00">yes</text>+</g>+<!-- fold3 -->+<g id="node15" class="node">+<title>fold3</title>+<polygon fill="none" stroke="black" points="1333,-290 1154,-252 1333,-214 1512,-252 1333,-290"/>+<text text-anchor="middle" x="1333" y="-255.8" font-family="Times,serif" font-size="14.00">Only that and examine</text>+<text text-anchor="middle" x="1333" y="-240.8" font-family="Times,serif" font-size="14.00">the original subtrees?</text>+</g>+<!-- fold1->fold3 -->+<g id="edge24" class="edge">+<title>fold1->fold3</title>+<path fill="none" stroke="black" d="M1082.89,-352.25C1135.3,-331.45 1208.94,-302.23 1262.74,-280.88"/>+<polygon fill="black" stroke="black" points="1264.2,-284.07 1272.21,-277.12 1261.62,-277.56 1264.2,-284.07"/>+<text text-anchor="middle" x="1203" y="-311.8" font-family="Times,serif" font-size="14.00">no</text>+</g>+<!-- cata -->+<g id="node21" class="node">+<title>cata</title>+<ellipse fill="none" stroke="black" cx="875" cy="-125" rx="55.49" ry="18"/>+<text text-anchor="middle" x="875" y="-121.3" font-family="Times,serif" font-size="14.00">Use cata!</text>+</g>+<!-- fold2->cata -->+<g id="edge25" class="edge">+<title>fold2->cata</title>+<path fill="none" stroke="black" d="M948.27,-219.46C931.5,-198.07 909.66,-170.21 894.2,-150.49"/>+<polygon fill="black" stroke="black" points="896.92,-148.29 887.99,-142.57 891.41,-152.6 896.92,-148.29"/>+<text text-anchor="middle" x="941.5" y="-184.8" font-family="Times,serif" font-size="14.00">yes</text>+</g>+<!-- histo -->+<g id="node22" class="node">+<title>histo</title>+<ellipse fill="none" stroke="black" cx="1007" cy="-125" rx="58.49" ry="18"/>+<text text-anchor="middle" x="1007" y="-121.3" font-family="Times,serif" font-size="14.00">Use histo!</text>+</g>+<!-- fold2->histo -->+<g id="edge26" class="edge">+<title>fold2->histo</title>+<path fill="none" stroke="black" d="M982.47,-216.18C987.92,-196.16 994.65,-171.39 999.69,-152.88"/>+<polygon fill="black" stroke="black" points="1003.12,-153.62 1002.36,-143.05 996.36,-151.78 1003.12,-153.62"/>+<text text-anchor="middle" x="1001" y="-184.8" font-family="Times,serif" font-size="14.00">no</text>+</g>+<!-- fold4 -->+<g id="node16" class="node">+<title>fold4</title>+<polygon fill="none" stroke="black" points="1298,-163 1152,-125 1298,-87 1444,-125 1298,-163"/>+<text text-anchor="middle" x="1298" y="-128.8" font-family="Times,serif" font-size="14.00">What do you do to</text>+<text text-anchor="middle" x="1298" y="-113.8" font-family="Times,serif" font-size="14.00">each subtree?</text>+</g>+<!-- fold3->fold4 -->+<g id="edge27" class="edge">+<title>fold3->fold4</title>+<path fill="none" stroke="black" d="M1323.16,-215.85C1319.25,-201.88 1314.7,-185.65 1310.56,-170.86"/>+<polygon fill="black" stroke="black" points="1313.84,-169.57 1307.77,-160.89 1307.09,-171.46 1313.84,-169.57"/>+<text text-anchor="middle" x="1329.5" y="-184.8" font-family="Times,serif" font-size="14.00">yes</text>+</g>+<!-- gcata -->+<g id="node20" class="node">+<title>gcata</title>+<ellipse fill="none" stroke="black" cx="1563" cy="-125" rx="101.23" ry="37.45"/>+<text text-anchor="middle" x="1563" y="-136.3" font-family="Times,serif" font-size="14.00">Write your own</text>+<text text-anchor="middle" x="1563" y="-121.3" font-family="Times,serif" font-size="14.00">recursion scheme</text>+<text text-anchor="middle" x="1563" y="-106.3" font-family="Times,serif" font-size="14.00">(using gcata)!</text>+</g>+<!-- fold3->gcata -->+<g id="edge28" class="edge">+<title>fold3->gcata</title>+<path fill="none" stroke="black" d="M1382.06,-224.34C1415.87,-205.96 1461.17,-181.34 1497.98,-161.34"/>+<polygon fill="black" stroke="black" points="1500.03,-164.21 1507.15,-156.36 1496.69,-158.06 1500.03,-164.21"/>+<text text-anchor="middle" x="1470" y="-184.8" font-family="Times,serif" font-size="14.00">no</text>+</g>+<!-- zygo -->+<g id="node23" class="node">+<title>zygo</title>+<ellipse fill="none" stroke="black" cx="1232" cy="-18" rx="57.39" ry="18"/>+<text text-anchor="middle" x="1232" y="-14.3" font-family="Times,serif" font-size="14.00">Use zygo!</text>+</g>+<!-- fold4->zygo -->+<g id="edge29" class="edge">+<title>fold4->zygo</title>+<path fill="none" stroke="black" d="M1277.84,-91.93C1268.32,-76.79 1257.12,-58.96 1248.17,-44.73"/>+<polygon fill="black" stroke="black" points="1250.94,-42.56 1242.66,-35.95 1245.02,-46.28 1250.94,-42.56"/>+<text text-anchor="middle" x="1301" y="-57.8" font-family="Times,serif" font-size="14.00">Apply cata</text>+</g>+<!-- para -->+<g id="node24" class="node">+<title>para</title>+<ellipse fill="none" stroke="black" cx="1364" cy="-18" rx="56.59" ry="18"/>+<text text-anchor="middle" x="1364" y="-14.3" font-family="Times,serif" font-size="14.00">Use para!</text>+</g>+<!-- fold4->para -->+<g id="edge30" class="edge">+<title>fold4->para</title>+<path fill="none" stroke="black" d="M1324.61,-93.62C1330.73,-85.88 1336.93,-77.37 1342,-69 1346.42,-61.7 1350.45,-53.35 1353.82,-45.6"/>+<polygon fill="black" stroke="black" points="1357.12,-46.79 1357.72,-36.21 1350.65,-44.11 1357.12,-46.79"/>+<text text-anchor="middle" x="1404.5" y="-57.8" font-family="Times,serif" font-size="14.00">Something else</text>+</g>+<!-- unfold2 -->+<g id="node18" class="node">+<title>unfold2</title>+<polygon fill="none" stroke="black" points="183,-290 14,-252 183,-214 352,-252 183,-290"/>+<text text-anchor="middle" x="183" y="-255.8" font-family="Times,serif" font-size="14.00">Do you only generate</text>+<text text-anchor="middle" x="183" y="-240.8" font-family="Times,serif" font-size="14.00">1 layer at a time?</text>+</g>+<!-- unfold1->unfold2 -->+<g id="edge32" class="edge">+<title>unfold1->unfold2</title>+<path fill="none" stroke="black" d="M471.74,-352.7C409.48,-331.2 320.47,-300.47 257.78,-278.82"/>+<polygon fill="black" stroke="black" points="258.54,-275.38 247.95,-275.43 256.26,-282 258.54,-275.38"/>+<text text-anchor="middle" x="397.5" y="-311.8" font-family="Times,serif" font-size="14.00">yes</text>+</g>+<!-- unfold3 -->+<g id="node19" class="node">+<title>unfold3</title>+<polygon fill="none" stroke="black" points="579,-290 370,-252 579,-214 788,-252 579,-290"/>+<text text-anchor="middle" x="579" y="-255.8" font-family="Times,serif" font-size="14.00">Only that and by returning</text>+<text text-anchor="middle" x="579" y="-240.8" font-family="Times,serif" font-size="14.00">pre-built subtrees?</text>+</g>+<!-- unfold1->unfold3 -->+<g id="edge33" class="edge">+<title>unfold1->unfold3</title>+<path fill="none" stroke="black" d="M554.65,-342.51C558.38,-328.79 562.7,-312.92 566.66,-298.38"/>+<polygon fill="black" stroke="black" points="570.08,-299.14 569.32,-288.57 563.32,-297.31 570.08,-299.14"/>+<text text-anchor="middle" x="573" y="-311.8" font-family="Times,serif" font-size="14.00">no</text>+</g>+<!-- ana -->+<g id="node25" class="node">+<title>ana</title>+<ellipse fill="none" stroke="black" cx="121" cy="-125" rx="51.99" ry="18"/>+<text text-anchor="middle" x="121" y="-121.3" font-family="Times,serif" font-size="14.00">Use ana!</text>+</g>+<!-- unfold2->ana -->+<g id="edge34" class="edge">+<title>unfold2->ana</title>+<path fill="none" stroke="black" d="M166.39,-217.5C156.2,-196.96 143.35,-171.05 133.92,-152.05"/>+<polygon fill="black" stroke="black" points="137.05,-150.48 129.47,-143.07 130.78,-153.59 137.05,-150.48"/>+<text text-anchor="middle" x="167.5" y="-184.8" font-family="Times,serif" font-size="14.00">yes</text>+</g>+<!-- futu -->+<g id="node27" class="node">+<title>futu</title>+<ellipse fill="none" stroke="black" cx="246" cy="-125" rx="54.69" ry="18"/>+<text text-anchor="middle" x="246" y="-121.3" font-family="Times,serif" font-size="14.00">Use futu!</text>+</g>+<!-- unfold2->futu -->+<g id="edge35" class="edge">+<title>unfold2->futu</title>+<path fill="none" stroke="black" d="M199.88,-217.5C210.23,-196.96 223.29,-171.05 232.87,-152.05"/>+<polygon fill="black" stroke="black" points="236.02,-153.58 237.39,-143.07 229.77,-150.43 236.02,-153.58"/>+<text text-anchor="middle" x="227" y="-184.8" font-family="Times,serif" font-size="14.00">no</text>+</g>+<!-- apo -->+<g id="node26" class="node">+<title>apo</title>+<ellipse fill="none" stroke="black" cx="486" cy="-125" rx="51.99" ry="18"/>+<text text-anchor="middle" x="486" y="-121.3" font-family="Times,serif" font-size="14.00">Use apo!</text>+</g>+<!-- unfold3->apo -->+<g id="edge36" class="edge">+<title>unfold3->apo</title>+<path fill="none" stroke="black" d="M554.57,-218.16C538.88,-197.08 518.85,-170.15 504.49,-150.85"/>+<polygon fill="black" stroke="black" points="507.1,-148.5 498.33,-142.57 501.49,-152.68 507.1,-148.5"/>+<text text-anchor="middle" x="550.5" y="-184.8" font-family="Times,serif" font-size="14.00">yes</text>+</g>+<!-- gana -->+<g id="node28" class="node">+<title>gana</title>+<ellipse fill="none" stroke="black" cx="657" cy="-125" rx="101.23" ry="37.45"/>+<text text-anchor="middle" x="657" y="-136.3" font-family="Times,serif" font-size="14.00">Write your own</text>+<text text-anchor="middle" x="657" y="-121.3" font-family="Times,serif" font-size="14.00">recursion scheme</text>+<text text-anchor="middle" x="657" y="-106.3" font-family="Times,serif" font-size="14.00">(using gana)!</text>+</g>+<!-- unfold3->gana -->+<g id="edge37" class="edge">+<title>unfold3->gana</title>+<path fill="none" stroke="black" d="M599.9,-217.5C608.88,-203.11 619.5,-186.09 629.14,-170.65"/>+<polygon fill="black" stroke="black" points="632.35,-172.12 634.67,-161.78 626.41,-168.41 632.35,-172.12"/>+<text text-anchor="middle" x="631" y="-184.8" font-family="Times,serif" font-size="14.00">no</text>+</g>+<!-- same_as_input_type->start_folds -->+<g id="edge14" class="edge">+<title>same_as_input_type->start_folds</title>+<path fill="none" stroke="black" d="M517.7,-568.42C610.64,-547.27 788.72,-506.74 879.99,-485.97"/>+<polygon fill="black" stroke="black" points="880.91,-489.35 889.88,-483.72 879.36,-482.53 880.91,-489.35"/>+</g>+<!-- same_as_output_type->start_unfolds -->+<g id="edge16" class="edge">+<title>same_as_output_type->start_unfolds</title>+<path fill="none" stroke="black" d="M292.15,-567.86C378.46,-547.23 538.24,-509.04 626.45,-487.95"/>+<polygon fill="black" stroke="black" points="627.41,-491.32 636.32,-485.59 625.78,-484.51 627.41,-491.32"/>+</g>+<!-- neither->start_refolds -->+<g id="edge18" class="edge">+<title>neither->start_refolds</title>+<path fill="none" stroke="black" d="M88.94,-568.32C97.72,-564.25 107.63,-560.06 117,-557 230.35,-519.93 367.15,-495.5 448.67,-482.98"/>+<polygon fill="black" stroke="black" points="449.46,-486.4 458.83,-481.44 448.41,-479.48 449.46,-486.4"/>+</g>+<!-- start -->+<g id="node32" class="node">+<title>start</title>+<ellipse fill="none" stroke="black" cx="505" cy="-1037" rx="33.29" ry="18"/>+<text text-anchor="middle" x="505" y="-1033.3" font-family="Times,serif" font-size="14.00">start</text>+</g>+<!-- start->decision0 -->+<g id="edge1" class="edge">+<title>start->decision0</title>+<path fill="none" stroke="black" d="M505,-1018.88C505,-1011.25 505,-1001.83 505,-992.31"/>+<polygon fill="black" stroke="black" points="508.5,-992.02 505,-982.02 501.5,-992.02 508.5,-992.02"/>+</g>+</g>+</svg>
recursion-schemes.cabal view
@@ -1,6 +1,6 @@ name: recursion-schemes category: Control, Recursion-version: 5.2.2.1+version: 5.2.2.2 license: BSD2 cabal-version: 1.18 license-file: LICENSE@@ -15,10 +15,10 @@ synopsis: Representing common recursion patterns as higher-order functions description: Many recursive functions share the same structure, e.g. pattern-match on the input and, depending on the data constructor, either recur on a smaller input or terminate the recursion with the base case. Another one: start with a seed value, use it to produce the first element of an infinite list, and recur on a modified seed in order to produce the rest of the list. Such a structure is called a recursion scheme. Using higher-order functions to implement those recursion schemes makes your code clearer, faster, and safer. See README for details. -tested-with: GHC==7.4.2, GHC==7.6.3, GHC==7.8.4, GHC==7.10.3, GHC==8.0.2, GHC==8.2.2, GHC==8.4.4, GHC==8.6.5, GHC==8.8.3, GHC==8.10.1+tested-with: GHC==7.4.2, GHC==7.6.3, GHC==7.8.4, GHC==7.10.3, GHC==8.0.2, GHC==8.2.2, GHC==8.4.4, GHC==8.6.5, GHC==8.8.4, GHC==8.10.7, GHC==9.0.1, GHC==9.2.1 build-type: Simple-extra-doc-files: docs/github-compression.png+extra-doc-files: docs/github-compression.png docs/flowchart.svg extra-source-files: CHANGELOG.markdown .gitignore README.markdown include/recursion-schemes-common.h source-repository head@@ -83,7 +83,7 @@ if flag(template-haskell) build-depends:- template-haskell >= 2.5.0.0 && < 2.18,+ template-haskell >= 2.5.0.0 && < 2.19, base-orphans >= 0.5.4 && < 0.9, th-abstraction >= 0.4 && < 0.5 exposed-modules:
src/Data/Functor/Foldable/TH.hs view
@@ -30,6 +30,8 @@ -- $setup -- >>> :set -XTemplateHaskell -XTypeFamilies -XDeriveTraversable -XScopedTypeVariables -- >>> import Data.Functor.Foldable+-- >>> import Language.Haskell.TH (Q)+-- >>> let asQ :: Q a -> Q a; asQ = id -- | Build base functor with a sensible default configuration. --@@ -111,7 +113,7 @@ -- >>> :t AddF -- AddF :: r -> r -> ExprF a r ----- >>> data Rose f a = Rose a (f (Rose f a)); makeBaseFunctor [d| instance Functor f => Recursive (Rose f a) |]+-- >>> data Rose f a = Rose a (f (Rose f a)); makeBaseFunctor $ asQ [d| instance Functor f => Recursive (Rose f a) |] -- -- >>> :t RoseF -- RoseF :: a -> f r -> RoseF f a r@@ -328,7 +330,11 @@ mkMorphism nFrom nTo args = for args $ \ci -> do let n = constructorName ci fs <- replicateM (length (constructorFields ci)) (newName "x")+#if MIN_VERSION_template_haskell(2,18,0)+ pure $ Clause [ConP (nFrom n) [] (map VarP fs)] -- patterns+#else pure $ Clause [ConP (nFrom n) (map VarP fs)] -- patterns+#endif (NormalB $ foldl AppE (ConE $ nTo n) (map VarE fs)) -- body [] -- where dec