2020-06-09 15:56:11 +04:00
|
|
|
|
|
|
|
module Product where
|
|
|
|
|
2020-06-10 22:37:02 +04:00
|
|
|
import qualified Data.Text as Text
|
|
|
|
|
2020-06-09 15:56:11 +04:00
|
|
|
import Pretty
|
|
|
|
|
|
|
|
data Product xs where
|
|
|
|
Nil :: Product '[]
|
|
|
|
Cons :: { pHead :: x, pTail :: Product xs } -> Product (x : xs)
|
|
|
|
|
|
|
|
instance Pretty (Product xs) => Show (Product xs) where
|
|
|
|
show = show . PP
|
|
|
|
|
|
|
|
class Contains x xs where
|
|
|
|
getElem :: Product xs -> x
|
|
|
|
putElem :: x -> Product xs -> Product xs
|
|
|
|
|
|
|
|
instance {-# OVERLAPS #-} Contains x (x : xs) where
|
|
|
|
getElem (Cons x _) = x
|
|
|
|
putElem x (Cons _ xs) = Cons x xs
|
|
|
|
|
|
|
|
instance Contains x xs => Contains x (y : xs) where
|
|
|
|
getElem (Cons _ xs) = getElem xs
|
|
|
|
putElem x (Cons y xs) = Cons y (putElem x xs)
|
|
|
|
|
2020-06-17 22:05:44 +04:00
|
|
|
modElem :: Contains x xs => (x -> x) -> Product xs -> Product xs
|
|
|
|
modElem f xs = putElem (f $ getElem xs) xs
|
2020-06-09 15:56:11 +04:00
|
|
|
|
|
|
|
instance Pretty (Product '[]) where
|
|
|
|
pp _ = "{}"
|
|
|
|
|
|
|
|
instance (Pretty x, Pretty (Product xs)) => Pretty (Product (x : xs)) where
|
2020-06-10 22:37:02 +04:00
|
|
|
pp (Cons x xs) =
|
|
|
|
if Text.null $ Text.strip ppx
|
|
|
|
then pp xs
|
|
|
|
else pp ppx <+> "&" <+> pp xs
|
|
|
|
where
|
2020-06-17 22:05:44 +04:00
|
|
|
ppx = ppToText x
|