0 | module Data.Linear.Copies
2 | import Data.Linear.Bifunctor
3 | import Data.Linear.Notation
8 | export infix 1 `Copies`
17 | data Copies : Nat -> (0 x : a) -> Type where
19 | (::) : (1 x : a) -> (1 copies : Copies n x) -> Copies (S n) x
23 | splitAt : (1 m : Nat) -> Copies (m + n) x -@ LPair (Copies m x) (Copies n x)
24 | splitAt Z xs = ([] # xs)
25 | splitAt (S m) (x :: xs) = let (ys # zs) = splitAt m xs in (x :: ys # zs)
29 | (++) : Copies m x -@ Copies n x -@ Copies (m + n) x
31 | (x :: xs) ++ ys = x :: (xs ++ ys)
35 | unzip : Copies m (Builtin.(#) x y) -@ LPair (Copies m x) (Copies m y)
37 | unzip ((x # y) :: xys) = let (xs # ys) = unzip xys in (x :: xs # y :: ys)
41 | pure : {1 n : Nat} -> (x : a) -> Copies n x
43 | pure {n = S n} x = x :: pure x
48 | (<*>) : Copies {a = a -@ b} m f -@ Copies m x -@ Copies m (f x)
50 | (f :: fs) <*> (x :: xs) = f x :: (fs <*> xs)
58 | (<$>) : (f : a -@ b) -> Copies m x -@ Copies m (f x)
60 | f <$> (x :: xs) = f x :: (f <$> xs)
64 | zip : Copies m x -@ Copies m y -@ Copies m (Builtin.(#) x y)
65 | zip as bs = (#) <$> as <*> bs
69 | extract : {0 x : a} -> 1 `Copies` x -@ a
74 | pair : {0 x : a} -> 2 `Copies` x -@ LPair a a
75 | pair y = bimap extract extract (splitAt 1 y)