Last active
April 5, 2023 11:07
-
-
Save pdaoust/7815423 to your computer and use it in GitHub Desktop.
Higher-order functions for Sass 3.3 -- now that we've got the `call()` function in Sass, we can start to compose functions. We don't have the benefit of anonymous functions, of course, but this is real functional programming, folks!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 'map', 'transform', 'select', or 'project' function. Iterate over a list, | |
// performing a function on each item, and collecting the new items. Each | |
// function takes an item as a first argument and returns a transformed item. | |
// You can pass additional arguments to the function too, which is a decent poor | |
// man's function composition. | |
// (I didn't call this f-map because the term 'map' is already used in Sass to | |
// denote a hash or dictionary.) | |
@function f-apply($func, $list, $args...) { | |
$new-list: (); | |
@each $item in $list { | |
$new-list: append($new-list, call($func, $item, $args...)); | |
} | |
@return $new-list; | |
} | |
// Reduce a list to a single value. Each function takes the previous value, an | |
// item, and additional arguments, and returns a transformed value. Sadly, you | |
// can't leave out the initial value (can't have default arguments before rest | |
// arguments), so if you don't want an initial value, set it to null. | |
@function f-fold($func, $list, $initial, $args...) { | |
$start: 1; | |
@if $initial == null { | |
// If there's no initial value, use the first in the list. | |
$start: 2; | |
$initial: nth($list, 1); | |
} | |
$prev: $initial; | |
@for $i from $start through length($list) { | |
$next: nth($list, $i); | |
$prev: call($func, $prev, $next, $args...); | |
} | |
@return $prev; | |
} | |
// Filter items from a list. Each function takes an item (and additional | |
// arguments) and returns a boolean value indicating whether the item passed the | |
// filter. | |
@function f-filter($func, $list, $args...) { | |
$new-list: (); | |
@each $item in $list { | |
@if call($func, $item, $args...) { | |
$new-list: append($new-list, $item); | |
} | |
} | |
@return $new-list; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Fucking A, man. :)