# Path: base.py
# def DT(*members, **opts):
#     members = list(members)
#     name = members.pop(0)
#     t = type(name, (Structured,), {'ctors': [], '_opts': opts})
#     ctor = _make_ctor(name, members, t)
#     _dt_form(t, None)
#     DATATYPES[name] = t
#     return ctor
# 
# def ADT(*ctors, **opts):
#     ctors = list(ctors)
#     tname = ctors.pop(0)
#     derivedFrom = None
#     derivedSubsts = None
#     if isinstance(tname, tuple):
#         if len(tname) == 3:
#             tname, derivedFrom, subs = tname
#             derivedSubsts = dict((extrinsic(FormSpec,s), extrinsic(FormSpec,d))
#                                  for s, d in subs.iteritems())
#         else:
#             tname, derivedFrom = tname
#     t = type(tname, (Structured,), {'ctors': [], '_opts': opts})
#     data = [t]
#     ctor_ix = 0
# 
#     def setup_ctor(name, members):
#         d = _make_ctor(name, members, t)
#         d.__module__ = tname
#         d._ctor_ix = ctor_ix
#         return d
# 
#     tvars = None
#     if derivedFrom:
#         tvars = {}
#         shortcut = CopiedCtors()
#         data.append(shortcut)
#         for ctor in derivedFrom.ctors:
#             # copy ctor
#             members = []
#             fields = extrinsic(FormSpec, ctor).fields
#             for field, val in ezip(fields, ctor.__slots__[:-1]):
#                 newType = derive_copied_ctor_type(field.type, derivedFrom, t,
#                         derivedSubsts or {}, tvars)
#                 members.append((val, newType))
# 
#             ctor_nm = ctor.__name__
#             d = setup_ctor(ctor_nm, members)
#             key = '%s.%s' % (tname, ctor_nm)
#             CTORS[d] = ctor_nm #key
#             ctor_ix += 1
#             setattr(shortcut, ctor_nm, d)
# 
#         # restore name->tv mapping
#         tvars = dict((extrinsic(Name, tv), tv) for tv in tvars.itervalues())
# 
#     while ctors:
#         ctor = ctors.pop(0)
#         members = []
#         while ctors and not isinstance(ctors[0], basestring):
#             members.append(ctors.pop(0))
#         d = setup_ctor(ctor, members)
#         ctor_ix += 1
#         data.append(d)
#     _dt_form(t, tvars)
#     DATATYPES[tname] = t
#     return tuple(data)
# 
# def annot(t):
#     return lambda func: func
# 
# def cdecl(name, type):
#     return None
# 
# def hint(e, **kwargs):
#     return e
# 
# def match(atom, *cases):
#     # Block form
#     if len(cases) == 0:
#         return BlockMatcher(atom)
#     elif len(cases) == 1 and isinstance(cases[0], basestring):
#         # shortcut for single-case
#         cases = ((cases[0], lambda *ss: ss[0] if len(ss) == 1 else ss),)
#     # Try all the cases, find the first that doesn't fail
#     for (case, f) in cases:
#         call_args = match_try(atom, _get_match_case(case))
#         if call_args is not None:
#             return f(*(v for k, v in call_args))
#     case_list = ''.join('* %s -> %s\n' % (p, f) for p, f in cases)
#     assert False, "Match failed.\nVALUE:\n%r\nCASES:\n%s" % (atom, case_list)
# 
# def new_extrinsic(label, t, omni=False):
#     if t is not None:
#         tvars = {}
#         t = parse_new_type(t, tvars)
#     return ExtInfo(label, t, [{}] if omni else [], [])


from base import DT, ADT, annot, cdecl, hint, match, new_extrinsic
from maybe import *

(List, Cons, Nil) = ADT('List', 'Cons', ('car', 'a'), ('cdr', 'List(a)'),
                                'Nil')

# XXX antiquated
Set = DT('Set', ('contents', ['a']))

# Path: base.py
# def DT(*members, **opts):
#     members = list(members)
#     name = members.pop(0)
#     t = type(name, (Structured,), {'ctors': [], '_opts': opts})
#     ctor = _make_ctor(name, members, t)
#     _dt_form(t, None)
#     DATATYPES[name] = t
#     return ctor
# 
# def ADT(*ctors, **opts):
#     ctors = list(ctors)
#     tname = ctors.pop(0)
#     derivedFrom = None
#     derivedSubsts = None
#     if isinstance(tname, tuple):
#         if len(tname) == 3:
#             tname, derivedFrom, subs = tname
#             derivedSubsts = dict((extrinsic(FormSpec,s), extrinsic(FormSpec,d))
#                                  for s, d in subs.iteritems())
#         else:
#             tname, derivedFrom = tname
#     t = type(tname, (Structured,), {'ctors': [], '_opts': opts})
#     data = [t]
#     ctor_ix = 0
# 
#     def setup_ctor(name, members):
#         d = _make_ctor(name, members, t)
#         d.__module__ = tname
#         d._ctor_ix = ctor_ix
#         return d
# 
#     tvars = None
#     if derivedFrom:
#         tvars = {}
#         shortcut = CopiedCtors()
#         data.append(shortcut)
#         for ctor in derivedFrom.ctors:
#             # copy ctor
#             members = []
#             fields = extrinsic(FormSpec, ctor).fields
#             for field, val in ezip(fields, ctor.__slots__[:-1]):
#                 newType = derive_copied_ctor_type(field.type, derivedFrom, t,
#                         derivedSubsts or {}, tvars)
#                 members.append((val, newType))
# 
#             ctor_nm = ctor.__name__
#             d = setup_ctor(ctor_nm, members)
#             key = '%s.%s' % (tname, ctor_nm)
#             CTORS[d] = ctor_nm #key
#             ctor_ix += 1
#             setattr(shortcut, ctor_nm, d)
# 
#         # restore name->tv mapping
#         tvars = dict((extrinsic(Name, tv), tv) for tv in tvars.itervalues())
# 
#     while ctors:
#         ctor = ctors.pop(0)
#         members = []
#         while ctors and not isinstance(ctors[0], basestring):
#             members.append(ctors.pop(0))
#         d = setup_ctor(ctor, members)
#         ctor_ix += 1
#         data.append(d)
#     _dt_form(t, tvars)
#     DATATYPES[tname] = t
#     return tuple(data)
# 
# def annot(t):
#     return lambda func: func
# 
# def cdecl(name, type):
#     return None
# 
# def hint(e, **kwargs):
#     return e
# 
# def match(atom, *cases):
#     # Block form
#     if len(cases) == 0:
#         return BlockMatcher(atom)
#     elif len(cases) == 1 and isinstance(cases[0], basestring):
#         # shortcut for single-case
#         cases = ((cases[0], lambda *ss: ss[0] if len(ss) == 1 else ss),)
#     # Try all the cases, find the first that doesn't fail
#     for (case, f) in cases:
#         call_args = match_try(atom, _get_match_case(case))
#         if call_args is not None:
#             return f(*(v for k, v in call_args))
#     case_list = ''.join('* %s -> %s\n' % (p, f) for p, f in cases)
#     assert False, "Match failed.\nVALUE:\n%r\nCASES:\n%s" % (atom, case_list)
# 
# def new_extrinsic(label, t, omni=False):
#     if t is not None:
#         tvars = {}
#         t = parse_new_type(t, tvars)
#     return ExtInfo(label, t, [{}] if omni else [], [])


# Path: bedrock.py
from base import DT, ADT, annot, cdecl, hint, match, new_extrinsic
from maybe import *


(List, Cons, Nil) = ADT('List', 'Cons', ('car', 'a'), ('cdr', 'List(a)'),
                                'Nil')

# XXX antiquated
Set = DT('Set', ('contents', ['a']))

Dict = DT('Dict', ('contents', [('k', 'v')]))