def map(fun, items):
    return (None if is_none(items)
            else pair(fun(head(items)),
                      map(fun, tail(items))))
def filter(predicate, sequence):
    return (None if is_none(sequence)
            else pair(head(sequence),
                      filter(predicate, tail(sequence)))
            if predicate(head(sequence))
            else filter(predicate, tail(sequence)))
def accumulate(op, initial, sequence):
    return (initial if is_none(sequence)
            else op(head(sequence),
                    accumulate(op, initial, tail(sequence))))
def enumerate_interval(low, high):
    return (None if low > high
            else pair(low,
                      enumerate_interval(low + 1, high)))
def append(list1, list2):
    return (list2 if is_none(list1)
            else pair(head(list1), append(tail(list1), list2)))
def flatmap(f, seq):
    return accumulate(append, None, map(f, seq))
def length(items):
    return (0 if is_none(items)
            else 1 + length(tail(items)))
def unique_triples(n):
    return flatmap(lambda i: flatmap(lambda j: map(lambda k: llist(i, j, k),
                                                   enumerate_interval(1, j - 1)),
                                     enumerate_interval(1, i - 1)),
                   enumerate_interval(1, n))
def plus(x, y):
    return x + y
def triples_that_sum_to(s, n):
    return filter(lambda items: accumulate(plus, 0, items) == s,
                  unique_triples(n))

print(length(triples_that_sum_to(10, 6)))

# expected: 3
