How would we feel about adding a class in the spirit of Align? I think we probably want a bit more granularity (akin to Apply and Divide). What about something that parallels the Apply/Applicative and Divide/Divisible classes:
class (Functor f) <= Align f where
align :: forall a b c. (These a b -> c) -> f a -> f b -> f c
With the laws:
-
Naturality
align f (map g x) (map h y) = align (f <<< bimap g h) x y
-
Associativity
associate :: These a (These b c) -> These (These a b) c
associate = case _ of
This x -> This (This x)
That (This x) -> This (That x)
That (That x) -> That x
That (Both x y) -> Both (That x) y
map associate (align identity x (align identity y z))
= align identity (align identity x y) z
Or, simpler
aligned :: forall a b f. Align f => f a -> f b -> f (These a b)
aligned = align identity
map associate (aligned x (aligned y z)) = aligned (aligned x y) z
class (Align f) <= Alignable f where
nil :: forall a. f a
With the laws
- Right identity
align f x nil = map (f <<< This) x
- Left identity
align f nil x = map (f <<< That) x
From Alignable, we can derive map as:
map f x = align (f <<< these identity identity const) x nil
The ultimate motivation for this is to define something similar to Crosswalk, so we can do things like:
parities :: Map Parity (List Int)
parities = crosswalk parity (range 1 10)
parity :: Int -> Map Parity Int
parity x
| x `mod` 2 == 0 = singleton Even x
| otherwise = singleton Odd x
data Parity
= Even
| Odd
derive instance eqParity :: Eq Parity
derive instance ordParity :: Ord Parity
But, I wanted to see if there was interest in Align first, before going further. Also, Crosswalk is such an out-there name. Maybe we can bike shed it before committing to Align/Alignable.
What do we think?
How would we feel about adding a class in the spirit of
Align? I think we probably want a bit more granularity (akin toApplyandDivide). What about something that parallels theApply/ApplicativeandDivide/Divisibleclasses:With the laws:
Naturality
Associativity
Or, simpler
With the laws
align f x nil = map (f <<< This) xalign f nil x = map (f <<< That) xFrom
Alignable, we can derivemapas:The ultimate motivation for this is to define something similar to
Crosswalk, so we can do things like:But, I wanted to see if there was interest in
Alignfirst, before going further. Also,Crosswalkis such an out-there name. Maybe we can bike shed it before committing toAlign/Alignable.What do we think?