tam-carre/and-collect/1.0.2

Unavailable. Nobody can download this version any more, with elm or with the Lamdera compiler: github.com/tam-carre/and-collect is gone (deleted or private); Software Heritage not asked yet (this run's --swh-calls were used up); no fork with tag 1.0.2 found (1 same-name repos checked); no cached copy. Use another version.

Details

and-collect

The goal of this experimental package is to simplify interdependent computations such as...

computeAnswer : Maybe Int
computeAnswer =
    getA
        |> Maybe.andThen
            (\a ->
                getB a
                    |> Maybe.andThen
                        (\b ->
                            getC a b
                                |> Maybe.andThen
                                    (\c ->
                                        solve a b c
                                    )
                        )
            )

...by allowing you to write them this way instead:

import Maybe.AndCollect as Maybe

computeAnswer : Maybe Int
computeAnswer =
    getA
        |> Maybe.andCollect getB
        |> Maybe.andCollect (\( a, b ) -> getC a b)
        |> Maybe.andThen (\( ( a, b ), c ) -> solve a b c)

This is much cleaner, even with elm-format, whose rules can make it difficult to work with interdependent computations. As this collects values into nested tuples, chaining andCollect too many times might still cause hard-to-read code.

The type signature for Maybe.AndCollect.andCollect is very similar to Maybe.andThen:

andThen    : (a -> Maybe b) -> Maybe a -> Maybe b
andCollect : (a -> Maybe b) -> Maybe a -> Maybe ( a, b )

This package provides andCollect combinators for Maybe, Result, Task, as well as a generic custom combinator for your own monad-like data types:

module RemoteData.Extra exposing (andCollect)

import AndCollect
import RemoteData exposing (RemoteData)

andCollect :
    (a -> RemoteData e b)
    -> RemoteData e a
    -> RemoteData e ( a, b )
andCollect callback oldRemoteData =
    AndCollect.custom
        RemoteData.andThen
        RemoteData.map
        callback
        oldRemoteData

This is how custom is implemented. (The LSP's inferred signature was used. Feedback or experimentation should be gathered to ensure the lack of higher-kinded types isn't causing any weird gotchas.)

custom :
    ((a -> mb) -> ma -> mab)
    -> ((x -> ( a, x )) -> b -> mb)
    -> (a -> b)
    -> ma
    -> mab
custom andThenFn mapFn callback input =
    input
        |> andThenFn
            (\inputUnwrapped ->
                callback inputUnwrapped
                    |> mapFn
                        (\callbackOutputUnwrapped ->
                            ( inputUnwrapped, callbackOutputUnwrapped )
                        )
            )