import { Eq } from 'fp-ts/lib/Eq'
import { pipe } from 'fp-ts/lib/function'
import * as M from 'fp-ts/lib/Map'
import * as O from 'fp-ts/lib/Option'
export * from 'fp-ts/lib/Map'
/**
* Allows removal, modification, or insertion of values into a map.
*
* The `alter` function is passed an `Option` and returns an `Option`,
* so the cases are:
* in: `some`, out: `some` -> update
* in: `some`, out: `none` -> remove
* in: `none`, out: `some` -> insert
* in: `none`, out: `none` -> noop
*/
export const alterAt = (eq: Eq) => (
k: K,
alter: (a: O.Option) => O.Option,
) => (map: Map): Map =>
pipe(
map,
M.lookup(eq)(k),
alter,
O.fold(
() => M.deleteAt(eq)(k)(map),
a => M.insertAt(eq)(k, a)(map),
),
)