Monads/List monad: Difference between revisions

Content added Content deleted
m (→‎{{header|Perl 6}}: Clarify expectations slightly)
(→‎{{header|Perl 6}}: Mention multis and show implementation)
Line 342: Line 342:
In Perl 6, bind is essentially map. I'll shadow map here but again, it '''removes''' capability, not adds it. Perl 6 also provided "hyper" operators which will descend into data structures and apply an operator / function to each member of that data structure.
In Perl 6, bind is essentially map. I'll shadow map here but again, it '''removes''' capability, not adds it. Perl 6 also provided "hyper" operators which will descend into data structures and apply an operator / function to each member of that data structure.


Here's a simple, if contrived example. take the numbers from 0 to 9, add 3 to each, find the divisors of those sums and print the list of divisors for each sum... in base 2. Again, a bind function was implemented but it is more limited than if we just used map directly.
Here's a simple, if contrived example. take the numbers from 0 to 9, add 3 to each, find the divisors of those sums and print the list of divisors for each sum... in base 2. Again, a bind function was implemented but it is more limited than if we just used map directly. The built in map method will work with either items or lists, here we need to implement a multi sub to handle either.


The * in the bind blocks are typically referred to as "whatever"; whatever + 3 etc. The guillemot (») is the hyper operator; descend into the data structure and apply the following operator/function to each member.
The * in the bind blocks are typically referred to as "whatever"; whatever + 3 etc. The guillemot (») is the hyper operator; descend into the data structure and apply the following operator/function to each member.
<lang perl6>sub bind (@list, &code) { @list.map: &code };
<lang perl6>multi bind (@list, &code) { @list.map: &code };

multi bind ($item, &code) { $item.&code };


sub divisors (Int $int) { gather for 1 .. $int { .take if $int %% $_ } }
sub divisors (Int $int) { gather for 1 .. $int { .take if $int %% $_ } }


put join "\n", (flat ^10).&bind(* + 3).&bind(*.&divisors)».base(2);</lang>
put join "\n", (flat ^10).&bind(* + 3).&bind(*.&divisors)».&bind(*.base: 2);</lang>


{{out}}
{{out}}