tam-carre/and-collect/1.0.0

NOTE: the latest version is 1.0.2

Rerouted (fork, verified). The original repository is gone. This copy comes from a fork that still has the tag. The Lamdera package server serves a copy recovered from https://github.com/mtamc/and-collect (a fork).

What we checked: Rebuilt with git archive from commit 08b6188aba00 of https://github.com/mtamc/and-collect (a fork) (zip prefix tam-carre-and-collect-08b6188/, America/Los_Angeles times): the zip is byte-identical to the one package.elm-lang.org recorded, SHA-1 fa7a963fb3e8a9eb034c45aae80eb5ed421fc690.

The Lamdera compiler uses this copy and prints a one-line notice saying so. elm itself fails to download this version.

Details · package.elm-lang.org's zip: https://github.com/tam-carre/and-collect/zipball/1.0.0/

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 this is the lack of higher-kinded types aren'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 )
                        )
            )