{'fraction_non_alphanumeric': 0.027046783625730993, 'fraction_numerical': 0.007309941520467836, 'mean_word_length': 5.71078431372549, 'pattern_counts': {'":': 0, '<': 0, '<?xml version=': 0, '>': 0, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
Programming and Reasoning with Infinite Structures Using Copatterns and Sized Types

Inductive data such as lists and trees is modeled category-theoretically as algebra where construction is the primary concept and elimination is obtained by initiality. In a more practical setting, functions are programmed by pattern matching on inductive data. Dually, coinductive structures such as streams and processes are modeled as coalgebras where destruction (or transition) is primary and construction rests on finality [Hag87]. Due to the coincidence of least and greatest fixed-point types [SP82] in lazy languages such as Haskell, the distinction between inductive and coinductive types is blurred in partial functional programming. As a consequence, coinductive structures are treated just as infinitely deep (or, non-well-founded) trees, and pattern matching on coinductive data is the dominant programming style. In total functional programming, which is underlying the dependently-typed proof assistants Coq [INR12] and Agda [Nor07], the distinction between induction and coinduction is vital for the soundness, and pattern matching on coinductive data leads to the loss of subject reduction [Gim96]. Further, in terms of expressive power, the productivity checker for definitions by coinduction lacks behind the termination checker for inductively defined functions.