{-# LANGUAGE GeneralizedNewtypeDeriving, DeriveFunctor, UndecidableInstances, StandaloneDeriving #-}
-- reference https://www.youtube.com/watch?v=BHjIl81HgfE
data MyType lst c = MyType {
myList :: lst Int
, myContent :: c
} deriving (Functor)
instance (Show (lst Int), Show c) => Show (MyType lst c) where
show (MyType l c) = "MyType " ++ show l ++ " " ++ show c
newtype Parsed a = Parsed a
deriving instance Show a => Show (Parsed a)
type DefaultMyType = MyType [] ()
type HalfBakedMyType c = MyType [] c
type FullyBackedMyType c = MyType [] (Parsed c)
defaultMyType :: DefaultMyType
defaultMyType = MyType [] ()
halfBake :: c -> DefaultMyType -> HalfBakedMyType c
halfBake s = fmap (const s)
fullyBake :: Foldable t => MyType lst (t a) -> MyType [] (Parsed (t a))
fullyBake t = t { myContent = Parsed (myContent t), myList = [1 .. length (myContent t)] }
main = do
print defaultMyType
let stepOne = halfBake "some content" defaultMyType
print stepOne
let stepTwo = fullyBake stepOne
print stepTwo