avh4-experimental/elm-transducers
{ "createdAt": "2015-06-03T02:48:00Z", "defaultBranch": "master", "description": "Composable transformation of sequences using clojure-inspired transducers", "fullName": "avh4-experimental/elm-transducers", "homepage": "https://package.elm-lang.org/packages/avh4-experimental/elm-transducers/latest/", "language": "Elm", "name": "elm-transducers", "pushedAt": "2018-08-31T07:45:45Z", "stargazersCount": 40, "topics": [], "updatedAt": "2025-02-06T13:54:39Z", "url": "https://github.com/avh4-experimental/elm-transducers"}elm-transducers
Section titled “elm-transducers”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 Lists.
Transducers enable efficient processing
Section titled “Transducers enable efficient processing”Transducers can be used to combine processing operations in a way that allows processing to be done more efficiently.
When using List.map, it is more efficient to compose multiple functions and then map the list with the composed function than to map the list with each function independently because the list will only be traversed once. Similarly, transducers can be used to process Lists more efficiently, but it is not limited to mapping operations. filter, take, drop, and any other transducer can be efficiently composed.
import List as Limport Transducer as T exposing ((>>>))
slowMapChain = [1, 2, 3] |> L.map ((+) 10) |> L.map toStringfastMapChain = [1, 2, 3] |> L.map ((+) 10 >> toString)
slowChain = [1, 2, 3] |> L.filter ((/=) 2) |> L.map toStringfastChain = [1, 2, 3] |> T.transduceList (T.filter ((/=) 2) >>> T.map toString)Transducers can be reused
Section titled “Transducers can be reused”Transducers can be reused with many different data types. List, Array, Set, Dict are supported by this library, and you can define your own transducer processes to work with other data types.
You can also define transducer processes that convert between types (for example, transducing from a List into a Set).
import Maybeimport Stringimport Transducer as T exposing ((>>>))import Result exposing (toMaybe)import Set exposing (Set)
parseValidInts = T.map String.toInt >>> T.map toMaybe >>> T.filter ((/=) Nothing) >>> T.map (Maybe.withDefault 0)
exampleList : List IntexampleList = T.transduceList parseValidInts [ "123", "-34", "35.0", "SDF", "7" ]
exampleConvert : Set IntexampleConvert = T.transduce List.foldr Set.insert Set.empty parseValidInts [ "123", "-34", "35.0", "SDF", "7" ]Differences from clojure’s tranducers
Section titled “Differences from clojure’s tranducers”- In elm, it is more natural for the
Reducertype to bea -> r -> rinstead ofr -> a -> r - Elm is pure, meaning that elm transducers cannot hide state. As a result, transducers cannot simply be functions as they are in clojure. This also means that the transducer type must include a type parameter for the transducer’s state.