Last active
April 2, 2018 10:43
-
-
Save danoneata/4e37604433ceef0927f72e212d4399e8 to your computer and use it in GitHub Desktop.
Python implemetation of Origami patterns
This file contains 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
from functools import singledispatch | |
class Document: | |
pass | |
class Paragraph(Document): | |
def __init__(self, text): | |
self.text = text | |
class Section(Document): | |
def __init__(self, title, docs): | |
self.title = title | |
self.docs = docs | |
def capitalize(s): | |
return s.upper() | |
@singledispatch | |
def fmap(doc, f): | |
pass | |
@fmap.register(Paragraph) | |
def _(para, f): | |
return Paragraph(f(para.text)) | |
@fmap.register(Section) | |
def _(sec, f): | |
docs_ = [fmap(doc, f) for doc in sec.docs] | |
return Section(title=sec.title, docs=docs_) | |
@singledispatch | |
def fold(doc, f, g): | |
pass | |
@fold.register(Paragraph) | |
def _(para, f, g): | |
return f(para.text) | |
@fold.register(Section) | |
def _(sec, f, g): | |
return g(sec.title, [fold(doc, f, g) for doc in sec.docs]) | |
# How to overload the unfold function? | |
def unfold(p, f, g, b): | |
if p(b): | |
return Paragraph(text=f(b)) | |
else: | |
title, bs = g(b) | |
return Section(title=title, docs=[unfold(p, f, g, b) for b in bs]) | |
def build(h): | |
return h(Paragraph, Section) | |
def build_doc(f, g): | |
return g( | |
"Introduction", [ | |
f("Ana are mere."), | |
f("Anna has apples."), | |
g("Conclusions", []), | |
]) | |
# Pair of functions that are used to translate a document to string | |
combine = ( | |
lambda s: "\t" + s, | |
lambda s, xs: "# " + s + '\n' + '\n'.join(xs), | |
) | |
def fmt(doc): | |
return fold(doc, *combine) | |
doc = Section( | |
title="Introduction", docs=[ | |
Paragraph(text="Ana are mere."), | |
Paragraph(text="Anna has apples."), | |
Section(title="Conclusions", docs=[]), | |
], | |
) | |
doc_dict = { | |
'type': "Section", | |
'title': "Introduction", | |
'children': [ | |
{ | |
'type': "Paragraph", | |
'text': "Ana are mere.", | |
}, | |
{ | |
'type': "Paragraph", | |
'text': "Ana has apples.", | |
}, | |
{ | |
'type': "Section", | |
'title': "Conclusions", | |
'children': [ | |
], | |
}, | |
] | |
} | |
def main(): | |
# Capitalize paragraphs and pretty print | |
print(fmt(fmap(doc, capitalize))) | |
# Build document from dictionary and pretty print | |
print(fmt(unfold( | |
lambda d: d['type'] == "Paragraph", | |
lambda d: d['text'], | |
lambda d: (d['title'], d['children']), | |
doc_dict))) | |
# Build document in an unstructured way and pretty print | |
print(fmt(build(build_doc))) | |
# Build directly the formatted string | |
print(build_doc(*combine)) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment