1 {-# LANGUAGE DataKinds #-}
2 {-# LANGUAGE DeriveTraversable #-}
4 {-# LANGUAGE PatternSynonyms #-}
5 {-# LANGUAGE ViewPatterns #-}
6 module Utils.MeasuredList
24 import Data.Eq (Eq(..))
25 import Data.Foldable (Foldable)
26 import Data.Functor (Functor(..))
27 import Data.Maybe (Maybe(..))
28 import Data.Ord (Ord(..))
29 import Data.Proxy (Proxy(..))
30 import Data.Traversable (Traversable(..))
32 import Numeric.Natural (Natural)
33 import Prelude (fromIntegral, error)
34 import Text.Show (Show(..))
35 import qualified Data.List as List
38 -- | A list whose length is known at the type-level.
39 newtype MeasuredList (n::Nat) a = ML [a]
40 deriving (Eq,Ord,Functor,Foldable,Traversable)
41 instance Show a => Show (MeasuredList n a) where
42 showsPrec p (ML xs) = showsPrec p xs
44 empty :: MeasuredList 0 a
46 cons :: a -> MeasuredList n a -> MeasuredList (n+1) a
47 cons x (ML xs) = ML (x:xs)
48 uncons :: (1<=n) => MeasuredList n a -> (a, MeasuredList (n-1) a)
49 uncons (ML (x:xs)) = (x, ML xs)
50 uncons (ML []) = error "MeasuredList.uncons: impossible happened"
52 pattern (:#) :: (1<=n) => a -> MeasuredList (n-1) a -> MeasuredList n a
53 pattern x:#xs <- (uncons -> (x,xs))
54 where x:#xs | ML l <- cons x xs = ML l
57 fromList :: forall n a. KnownNat n => [a] -> Maybe (MeasuredList n a)
58 fromList xs | List.length xs == fromIntegral (natVal (Proxy::Proxy n)) = Just (ML xs)
61 head :: (1<=n) => MeasuredList n a -> a
62 head (ML xs) = List.head xs
63 tail :: (1<=n) => MeasuredList n a -> MeasuredList (n-1) a
64 tail (ML xs) = ML (List.tail xs)
65 concat :: MeasuredList n a -> MeasuredList m a -> MeasuredList (n+m) a
66 concat (ML xs) (ML ys) = ML (xs List.++ ys)
67 reverse :: MeasuredList n a -> MeasuredList n a
68 reverse (ML xs) = ML (List.reverse xs)
69 length :: forall n a. KnownNat n => MeasuredList n a -> Natural
70 length _xs = natVal (Proxy::Proxy n)
72 splitAt :: forall i n a proxy.
73 KnownNat i => (i<=n) =>
74 proxy i -> MeasuredList n a -> (MeasuredList i a, MeasuredList (n-i) a)
75 splitAt _i (ML xs) = (ML ls, ML rs)
77 (ls,rs) = List.splitAt i xs
78 i = fromIntegral (natVal (Proxy::Proxy i))
80 zip :: MeasuredList n a -> MeasuredList n b -> MeasuredList n (a,b)
81 zip (ML as) (ML bs) = ML (List.zip as bs)
82 zipWith :: (a -> b -> c) -> MeasuredList n a -> MeasuredList n b -> MeasuredList n c
83 zipWith f (ML as) (ML bs) = ML (List.zipWith f as bs)