Skip to content

Instantly share code, notes, and snippets.

@danbornside
Last active September 9, 2018 02:21
Show Gist options
  • Save danbornside/5277a399424e7dcab2938c8a9deb6764 to your computer and use it in GitHub Desktop.
Save danbornside/5277a399424e7dcab2938c8a9deb6764 to your computer and use it in GitHub Desktop.
semigroups via wrapped `At`/`FoldableWithIndex`
import Control.Monad.State
import Control.Lens.At
import Control.Lens.Indexed
import Data.Functor.Identity
unionWith
:: (FoldableWithIndex (Index s) t, At s)
=> (a -> IxValue s) -> (a -> IxValue s -> IxValue s)
-> s -> t a -> s
unionWith a2b ab2b xs ys = execState (itraverse_ f ys) xs
where
f k y = at k %= Just . maybe (a2b y) (ab2b y)
newtype Wrapped f = Wrapped f
instance
( Eq k, Semigroup a, FoldableWithIndex k f
, Index (f a) ~ k, IxValue (f a) ~ a , At (f a)
) => Semigroup (Wrapped (f a)) where
Wrapped xs <> Wrapped ys = Wrapped $ unionWith id (flip (<>)) xs ys
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment