FP::StrictList - an FP::List that enforces list semantics
use FP::StrictList; use FP::Div 'inc'; use FP::List; my $l= strictlist (4,5)->map(*inc); ok is_strictlist $l; # O(1) use FP::Equal qw(equal is_equal); use FP::List 'null'; is_equal strictnull->cons(1), cons (1, strictnull); ok not equal strictnull->cons(1), cons (1, null); # false: `cons` from `FP::List` and `FP::StrictList` are the same # function but it takes the type of their second argument into # consideration.
FP::List does not enforce its pairs to only contain pairs or null in their rest (cdr) position. Which means that they may end in something else than a null (and operations encountering these will die with "improper list"). FP::StrictList does, which means that `is_strictlist` only needs to check the head pair to know whether it's a proper list.
Also, FP::StrictList maintains the list length within each pair, thus its `length` operation has O(1) complexity instead of O(n) like the `length` from FP::List.
Both of these features dictate that a StrictList can't be lazy, since (in a dynamically typed language) it's impossible to know the type that a promise will give without evaluating it, or know the length of the unevaluated tail.
Keep in mind that destruction of strict lists requires space on the C stack proportional to their length. You will want to increase the C stack size when handling big strict lists, lest your program will segfault.
Currently FP::StrictList mostly only offers method based functionality. It inherits all the methods from FP::List, but only re-exports those basic functions that are basic and don't have "list_" prefixes, and only on demand. The only special functions (and the only ones exported by default) are `strictnull`, `is_strictlist` and `strictlist`. Since StrictList enforcess list structure, methods are guaranteed to always work on the rest field of a pair. Hence, the suggestion is to simply use method calls and `the_method` from `FP::Ops` to pass methods as first class functions.
This is alpha software! Read the status section in the package README or on the website.