Skip to content

Instantly share code, notes, and snippets.

@danoneata
Last active April 2, 2018 10:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danoneata/4e37604433ceef0927f72e212d4399e8 to your computer and use it in GitHub Desktop.
Save danoneata/4e37604433ceef0927f72e212d4399e8 to your computer and use it in GitHub Desktop.
Python implemetation of Origami patterns
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