A transducer is a composable way of processing a series of values.
Many basic transducers correspond to functions you may be familiar with for
processing List
s.
import Maybe
import String
import Transducer exposing (..)
parseValidInts =
map String.toInt
|> composeWith (map toMaybe)
|> composeWith (filter ((/=) Nothing))
|> composeWith (map (Maybe.withDefault 0))
exampleList : List Int
exampleList =
transduceList parseValidInts [ "123", "-34", "35.0", "SDF", "7" ]
input -> result -> result
A reducer is a function taking an input and a value and produces a new value.
List.foldl : Reducer a b -> b -> List a -> b
{ init : Reducer b r -> r -> ( state
, r )
, step : Reducer b r -> Reducer a ( state
, r )
, complete : Reducer b r -> ( state
, r ) -> r
}
A transducer an init
value for it's internal state, a step
function that
transforms a Reducer into a Reducer of a new type, and a complete
function that
transforms a Reducer into a function collapsing the internal state.
When defining transducers, the type parameter r
should be left free.
Reducer input result -> result -> source -> result
A fold is function that takes a Reducer, an initial value, and input source, and returns a final value.
map : (a -> b) -> Transducer a b r ()
Apply a function to every value.
transduceList (map sqrt) [ 1, 4, 9 ] == [ 1, 2, 3 ]
filter : (a -> Basics.Bool) -> Transducer a a r ()
Keep only values that satisfy the predicate.
transduceList (filter isEven) (List.range 1 6) == [ 2, 4, 6 ]
take : Basics.Int -> Transducer a a r Basics.Int
Take the first n values.
transduceList (take 2) [ 1, 2, 3, 4 ] == [ 1, 2 ]
drop : Basics.Int -> Transducer a a r Basics.Int
Drop the first n values.
transduceList (drop 2) [ 1, 2, 3, 4 ] == [ 3, 4 ]
concatMap : (a -> List b) -> Transducer a b r ()
Map a given function onto a list and flatten the results.
transduceList (concatMap (\x -> [ x, x + 10 ])) [ 1, 2 ] == [ 1, 10, 2, 20 ]
dedupe : Transducer a a r (Maybe a)
Drop values that repeat the previous value.
transduceList dedupe [ 1, 1, 2, 2, 1 ] == [ 1, 2, 1 ]
partition : Basics.Int -> Transducer a (List a) r ( Basics.Int, List a )
Group a series of values into Lists of size n.
transduceList (partition 2) [ 1, 2, 3, 4, 5 ] == [ [ 1, 2 ], [ 3, 4 ], [ 5 ] ]
composeWith : Transducer b c r s2 -> Transducer a b ( s2, r ) s1 -> Transducer a c r ( s1, s2 )
Compose two transducers.
firstOperation
|> composeWith secondOperation
transduce : Fold a ( s, r ) x -> Reducer b r -> r -> Transducer a b r s -> x -> r
Apply a transducer.
transduceList : Transducer a b (List b) s -> List a -> List b
Apply a Transducer to a List, producing a List.
transduceList t xs == transduce List.foldr (::) [] t xs
transduceSet : Transducer a comparable (Set comparable) s -> Set a -> Set comparable
Apply a Transducer to a Set, producing a Set.
transduceSet t xs =
transduce Set.foldr Set.insert Set.empty t xs
transduceArray : Transducer a b (Array b) s -> Array a -> Array b
Apply a Transducer to an Array, producing an Array.
transduceArray t xs =
transduce Array.foldl Array.push Array.empty t xs