Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/lue-bird/elm-and-or
both or only one of them
https://github.com/lue-bird/elm-and-or
and-or either either-or-both elm these
Last synced: about 2 months ago
JSON representation
both or only one of them
- Host: GitHub
- URL: https://github.com/lue-bird/elm-and-or
- Owner: lue-bird
- License: mit
- Created: 2023-05-05T21:52:12.000Z (almost 2 years ago)
- Default Branch: master
- Last Pushed: 2023-05-06T11:09:46.000Z (almost 2 years ago)
- Last Synced: 2024-12-09T18:02:06.032Z (about 2 months ago)
- Topics: and-or, either, either-or-both, elm, these
- Language: Elm
- Homepage: https://dark.elm.dmy.fr/packages/lue-bird/elm-and-or/latest/
- Size: 26.4 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: changes.md
- Contributing: contributing.md
- License: LICENSE
Awesome Lists containing this project
README
> both or only one of them
# [`AndOr`](AndOr)
The basic types of this package look like this:
```elm
type AndOr first second
= Both ( first, second )
| Only (Or first second)type Or first second
= First first
| Second second
```Both types can be quite useful! ...But first
## ❌ misuse-cases
[`AndOr`](AndOr#AndOr) and [`Or`](Or#Or) are prone to misuse, just like `Maybe`, tuple, `Bool` etc.
When there is a representation of your data that's more descriptive, use that instead!
Example:
Modeling the result of an operation that can fail, succeed or succeed with warnings
```elm
type alias Fallible a =
AndOr a Error
```
This is problematic from multiple standpoints:
- Why should error and warning types be required to be the same?
- Why not have a unified case for success:
```elm
type alias Fallible a =
Or { result : a, warnings : List RecoverableError }
UnrecoverableError
```
- Who tells you that "first" means "success" and "second" means "error"? (or the other way round?)
- Why not use descriptive names:
```elm
type Fallible a
= Success { result : a, errors : List RecoverableError }
| UnrecoverableError UnrecoverableError
```## ✔️ use-cases
[`AndOr`](AndOr#AndOr) and [`Or`](Or#Or) are useful for generic operations where no descriptive names exist –
similar to how tuples are used for partition results because there is no information
on what each side means.- generic diffs
- see [`KeysSet.fold2From`](https://dark.elm.dmy.fr/packages/lue-bird/elm-keysset/latest/KeysSet#fold2From) which is similar to `Dict.merge` but more comprehensible and easier to work with thanks to [`AndOr`](AndOr#AndOr)
- map2 where overflow elements aren't disregarded:
```elm
List.AndOr.map2 : (AndOr a b -> c) -> ( List a, List b ) -> List c
List.AndOr.map2 combine lists =
case lists of
( firsts, [] ) ->
firsts
|> List.map
(\first -> Only (Or.First first) |> combine)
( [], seconds ) ->
seconds
|> List.map
(\first -> Only (Or.Second first) |> combine)
( firstHead :: firstTail, secondHead :: secondTail ) ->
(AndOr.Both firstHead secondHead |> combine)
:: List.AndOr.map2 combine firstTail secondTail
```
- type-safe partitioning
```elm
List.Or.partition : (a -> Or first second) -> (List a -> ( List first, List second ))
List.Or.partition chooseSide list =
case list of
[] ->
[]
head :: tail ->
let
consHead : ( List first, List second ) -> ( List first, List second )
consHead =
case head |> chooseSide of
First first ->
And.firstMap ((::) first)
Second second ->
And.secondMap ((::) second)
in
tail |> List.Or.partition chooseSide |> consHead
```## prior art – [`AndOr`](AndOr)
- [`joneshf/elm-these`](https://dark.elm.dmy.fr/packages/joneshf/elm-these/latest/)
- [haskell's `Data.These`](https://hackage.haskell.org/package/these-1.2/docs/Data-These.html)All of them don't separate out the "only one of both" case.
## prior art – [`Or`](Or)
- [`kingwither/elmeither`](https://dark.elm.dmy.fr/packages/kingwither/elmeither/latest/)
- (too few) simple helpers
- [`toastal/either`](https://dark.elm.dmy.fr/packages/toastal/either/latest/)
- a lot of helpers, though with weird haskell-ish names like `voidLeft` for setting, `singleton` for `Right` etc.
- [haskell's `Data.Either`](https://hackage.haskell.org/package/base-4.18.0.0/docs/Data-Either.html)All of them use `Left` and `Right` as variant names whereas [`Or`](Or#Or)'s `First` and `Second` are consistent with elm's tuple part names.
## suggestions?
The API is pretty slim, only covering the needs I could think of.
If you have an idea for a useful helper → [contribute](https://github.com/lue-bird/elm-and-or/blob/master/contributing.md)