Functional coverage tree: Difference between revisions

m
→‎Python: Composition of pure functions: Tidied, updated primitives.
(Added Wren)
m (→‎Python: Composition of pure functions: Tidied, updated primitives.)
Line 2,392:
delimiter = '|'
 
reportLines = lines(REPORT.splitlines()
columnTitles = init(columnNames(delimiter)(reportLines[0]))
 
# ------ SERIALISATION OF DECORATED PARSE TREE -------
print(titleLine(delimiter)(columnWidths)(
columnTitles + ['share of residue']
Line 2,401:
print(indentedLinesFromTree(' ', tabulation(columnWidths))(
 
# -------- TWO COMPUTATIONS BY TRAVERSAL ---------
withResidueShares(1.0)(
foldTree(weightedCoverage)(
 
# --- TREE FROM PARSE OF OUTLINE TEXT ----
fmapTree(
recordFromKeysDefaultsDelimiterAndLine(columnTitles)(
[str, float, float])(['?', 1.0, 0.0])(delimiter)columnTitles
)(
[str, float, float])([
'?', 1.0, 0.0
])(delimiter)
)(
forestFromLineIndents(indentLevelsFromLinesforestFromIndentLevels(
reportLines[1:]indentLevelsFromLines(
)) reportLines[01:]
)
)[0]
)
)
Line 2,419 ⟶ 2,425:
 
 
# ---- WEIGHTED COVERAGE, AND SHARE OF TOTAL RESIDUE -----------
 
# weightedCoverage :: Tree Dict ->
Line 2,429 ⟶ 2,435:
'''
def go(xs):
cws = [
cws = [(r['coverage'], r['weight']) for r in [root(x) for x in xs]]
(r['coverage'], r['weight']) for r
in [root(x) for x in xs]
]
totalWeight = reduce(lambda a, x: a + x[1], cws, 0)
return Node(dict(
Line 2,439 ⟶ 2,448:
}
))(xs)
return lambda xs: go(xs)
 
 
Line 2,448 ⟶ 2,457:
'''
def go(fraction, node):
[nodeRoot, nodeNest] = apListap([root, nest])([node])
weights = [root(x)['weight'] for x in nodeNest]
siblingsTotal = sum(weights)
Line 2,465 ⟶ 2,474:
 
 
# OUTLINE TABULATION -------------------- OUTLINE TABULATION ------------------
 
# tabulation :: [Int] -> String -> Dict -> String
Line 2,495 ⟶ 2,504:
 
 
# GENERIC AND REUSABLE FUNCTIONS -------------- GENERIC AND REUSABLE FUNCTIONS ------------
 
# Node :: a -> [Tree a] -> Tree a
Line 2,506 ⟶ 2,515:
 
 
# Tupleap (,<*>) :: [(a -> b)] -> ([a,] -> [b)]
def Tupleap(xfs):
'''Constructor for a pair of values,
possibly of two different types.
'''
return lambda y: (
x + (y,)
) if isinstance(x, tuple) else (x, y)
 
 
# apList (<*>) :: [(a -> b)] -> [a] -> [b]
def apList(fs):
'''The application of each of a list of functions,
to each of a list of values.
'''
def go(xs):
return liftA2List(identity)(fs)
return [
f(x) for (f, x)
in product(fs, xs)
]
return go
 
 
Line 2,548 ⟶ 2,552:
# concatMap :: (a -> [b]) -> [a] -> [b]
def concatMap(f):
'''A concatenated list or string over which a function fhas been mapped.
The list monad can be derived by using a function f which
has been mapped.
Thewraps listits monadoutput canin be derived by using an (a -> [b])list,
(using an empty list to represent computational failure).
function which wraps its output in a list (using an
empty list to represent computational failure).
'''
def go(xs):
return lambda xs: (''.join if isinstance(xs, str) else list)(
return chain.from_iterable(map(f, xs))
)return go
 
 
Line 2,565 ⟶ 2,568:
 
 
# first :: (a -> b) -> ((a, c) -> (b, c))
def firstArrow(f):
def first(f):
'''A simple function lifted to one which applies
'''A simple function lifted to a function over a tuple,
to a tuple, transforming only its first item.
with f applied only the first of two values.
'''
return lambda xy: Tuple(f(xy[0]), xy[1])(
xy[1]
)
 
 
Line 2,593 ⟶ 2,595:
def fmapTree(f):
'''A new tree holding the results of
applyingan application of f to each root in
the existing tree.
'''
def go(x):
return Node(f(x['root']))(
[gof(v) for v in x['nestroot']])
)([go(v) for v in x['nest']])
return lambda tree: go(tree)
 
 
Line 2,606 ⟶ 2,608:
def foldTree(f):
'''The catamorphism on trees. A summary
value obtaineddefined by a depth-first fold.
'''
def go(node):
return f(node['root'](node))([
go(x) for x in node['nest'](node)
])
return lambda tree: go(tree)
 
 
# forestFromLineIndentsforestFromIndentLevels :: [(Int, Stringa)] -> [Tree Stringa]
def forestFromLineIndentsforestFromIndentLevels(tuples):
'''A list of trees derived from a list of linesvalues paired
with integers giving their levels of indentation.
'''
def go(xs):
if xs:
(intIndent, txt)v = xs[0]
(firstTreeLines, rest) = span(
compose(lt(lambda x: intIndent), fst)< x[0]
)(xs[1:])
return [Node(txtv)(go(firstTreeLines))] + go(rest)
else:
return []
Line 2,636 ⟶ 2,638:
'''First member of a pair.'''
return tpl[0]
 
 
# identity :: a -> a
def identity(x):
'''The identity function.'''
return x
 
 
Line 2,651 ⟶ 2,647:
'''
indentTextPairs = list(map(
compose(firstArrowfirst(len), span(isSpace)),
xs
))
Line 2,658 ⟶ 2,654:
)(indentTextPairs))
return list(map(
firstArrowfirst(flip(div)(indentUnit)),
indentTextPairs
))
Line 2,670 ⟶ 2,666:
'''
def go(indent):
return lambda node: [f(indent, node['root'])] + concatMaplist(
goconcatMap(strTab + indent)
) go(node['nest']strTab + indent)
return lambda tree: unlines(go )(node['nest')(tree)])
)
return lambda tree: '\n'.join(go('')(tree))
 
 
Line 2,699 ⟶ 2,697:
'''
return s.isspace()
 
 
# liftA2List :: (a -> b -> c) -> [a] -> [b] -> [c]
def liftA2List(f):
'''The binary operator f lifted to a function over two
lists. f applied to each pair of arguments in the
cartesian product of xs and ys.
'''
return lambda xs: lambda ys: [
f(x)(y) for x, y in product(xs, ys)
]
 
 
# lines :: String -> [String]
def lines(s):
'''A list of strings,
(containing no newline characters)
derived from a single new-line delimited string.
'''
return s.splitlines()
 
 
Line 2,770 ⟶ 2,748:
span p xs is equivalent to (takeWhile p xs, dropWhile p xs).
'''
def match(ab):
b = ab[1]
return not b or not p(b[0])
 
def f(ab):
a, b = ab
return a + [b[0]], b[1:]
 
def go(xs):
lngreturn = lenuntil(match)(f)(([], xs))
return splitAt(go
until(lambda i: (lng == i) or not p(xs[i]))(succ)(0)
)(xs)
return lambda xs: go(xs)
 
 
# Unimplemented <- splitOn for lists (Eq a => [a] -> [a] -> [[a]])
# splitOn :: String -> String -> [String]
def splitOn(pat):
Line 2,786 ⟶ 2,768:
return lambda xs: (
xs.split(pat) if isinstance(xs, str) else None
)
 
 
# splitAt :: Int -> [a] -> ([a], [a])
def splitAt(n):
'''A tuple pairing the prefix of length n
with the rest of xs.
'''
return lambda xs: (xs[0:n], xs[n:])
 
 
# succ :: Enum a => a -> a
def succ(x):
'''The successor of a value.
For numeric types, (1 +).
'''
return 1 + x if isinstance(x, int) else (
chr(1 + ord(x))
)
 
Line 2,811 ⟶ 2,775:
'''String in lower case.'''
return s.lower()
 
 
# unlines :: [String] -> String
def unlines(xs):
'''A single string formed by the intercalation
of a list of strings with the newline character.
'''
return '\n'.join(xs)
 
 
Line 2,826 ⟶ 2,782:
The initial seed value is x.
'''
def go(f, x):
v =def g(x):
while not p( v): = x
vwhile =not fp(v):
return v = f(v)
return lambda f: lambda x: go(f, x) return v
return g
return go
 
 
9,655

edits