packages feed

describe-0.3.0.0: src/Data/Serialize/Describe/Combinators/FList.hs

module Data.Serialize.Describe.Combinators.FList where

import GHC.TypeNats
import Data.Proxy
import Data.Serialize.Describe
import Data.Word
import Data.Serialize.Describe.Combinators.Const
import Control.Monad

newtype FList (n :: Nat) a 
  = FList { unwrapFList :: [a] }
  deriving (Show) via [a]

class Nullable a where
  nullVal :: a

instance Nullable Word16 where
  nullVal = 0

instance Nullable (Const n a) where
  nullVal = Const

instance (KnownNat n, Nullable a, Describe a) => Describe (FList n a) where
  describe f = do
    let fixedLen = fromIntegral (natVal $ Proxy @n)
    fmap FList . forM [0..fixedLen - 1] $ \i -> 
      describe $ \l ->
        let actualLen = length . take fixedLen . unwrapFList $ f l
         in (!! i) . (<> replicate (fixedLen - actualLen) (nullVal @a)) . unwrapFList $ f l