/RepLib/Generics/RepLib/Vec.hs

http://replib.googlecode.com/ · Haskell · 106 lines · 73 code · 18 blank · 15 comment · 13 complexity · 3bed7b571190282a3a599ad59725f923 MD5 · raw file

  1. {-# LANGUAGE TemplateHaskell, ScopedTypeVariables,
  2. FlexibleInstances, FlexibleContexts,
  3. UndecidableInstances, MultiParamTypeClasses,
  4. TypeFamilies, EmptyDataDecls, TypeOperators, GADTs, MagicHash #-}
  5. {-# OPTIONS_GHC -fno-warn-orphans #-}
  6. -- | A definition of length-indexed vectors plus their representations
  7. module Generics.RepLib.Vec (
  8. Z,rZ,rZ1,S,rS,rS1,
  9. SNat(..),toSNat,
  10. Vec(..),rVec,rVec1
  11. )
  12. where
  13. import Generics.RepLib
  14. import GHC.Base (unsafeCoerce#)
  15. -- | Natural numbers
  16. data Z
  17. data S n
  18. $(derive [''Z, ''S])
  19. -- | Singleton GADT for natural numbers
  20. data SNat a where
  21. SZ :: SNat Z
  22. SS :: Rep n => SNat n -> SNat (S n)
  23. -- | Convert a representation of a natural number into a singleton
  24. -- WARNING: Only call this on *numbers*
  25. -- It demonstrates a deficiency of reps for void/abstract datatypes
  26. toSNat :: forall n. R n -> (SNat n)
  27. toSNat r =
  28. case gcast (SZ :: SNat n) of
  29. Just sz -> sz
  30. Nothing -> case gcast (SS (toSNat rm)) of
  31. toSNat r@(Data (DT "Generics.RepLib.Vec.Z" MNil) []) =
  32. case gcastR r rZ SZ of
  33. Just sz -> sz
  34. Nothing -> error "BUG"
  35. toSNat r@(Data (DT "Generics.RepLib.Vec.S" (rm :+: MNil)) []) =
  36. case gcastR r (rS (toSNat rm)) of
  37. Just i -> i
  38. Nothing -> error "impossible"
  39. -- (unsafeCoerce# (SS (toSNat rm)) :: SNat n)
  40. toSNat _ = error "BUG: toSNat can only be called with the representation of a natural number"
  41. -- | a tuple of n values of type a
  42. type family Tup a n :: *
  43. type instance Tup a Z = Nil
  44. type instance Tup a (S m) = a :*: (Tup a m)
  45. -- | a vector of n values of type a
  46. data Vec a n where
  47. VNil :: Vec a Z
  48. VCons :: Rep n => a -> Vec a n -> Vec a (S n)
  49. gTo :: forall a n . Rep n => SNat n -> (Tup a n) -> (Vec a n)
  50. gTo s = case s of
  51. SZ -> \Nil -> VNil
  52. SS sm -> \(a :*: l ) -> VCons a (gTo sm l)
  53. gFrom :: forall a n. Rep n => SNat n -> (Vec a n) -> Maybe (Tup a n)
  54. gFrom SZ = \ VNil -> Just Nil
  55. gFrom (SS sm) = \ (VCons a tl) -> do
  56. tl' <- gFrom sm tl
  57. return (a :*: tl')
  58. gMTup :: forall a n. (Rep a, Rep n) => R a -> SNat n -> MTup R (Tup a n)
  59. gMTup ra SZ = MNil
  60. gMTup ra (SS sm) = ra :+: gMTup ra sm
  61. vecEmb :: forall a n . Rep n => SNat n -> Emb (Tup a n) (Vec a n)
  62. vecEmb sn = (Emb { to = gTo sn,
  63. from = gFrom sn,
  64. labels = Nothing,
  65. name = "",
  66. fixity = Nonfix })
  67. -- | Rep of the vector type
  68. rVec :: forall a n. (Rep a, Rep n) => R (Vec a n)
  69. rVec =
  70. Data (DT "Generics.RepLib.Vec.Vec" ((rep :: R a) :+: (rep :: R n) :+: MNil))
  71. [ Con (vecEmb sn)
  72. (gMTup (rep :: R a) sn) ] where
  73. sn :: SNat n
  74. sn = toSNat rep
  75. gMTup1 :: forall a n ctx. (Rep a, Rep n, Sat (ctx a)) => R a -> SNat n -> MTup ctx (Tup a n)
  76. gMTup1 ra SZ = MNil
  77. gMTup1 ra (SS sm) = dict :+: gMTup1 ra sm
  78. rVec1 :: forall a n ctx. (Rep a, Rep n, Sat (ctx a)) => R1 ctx (Vec a n)
  79. rVec1 =
  80. Data1 (DT "Generics.RepLib.Vec.Vec" ((rep :: R a) :+: (rep :: R n) :+: MNil))
  81. [ Con (vecEmb sn)
  82. (gMTup1 (rep :: R a) sn) ] where
  83. sn :: SNat n
  84. sn = toSNat rep
  85. instance (Rep a, Rep n) => Rep (Vec a n) where
  86. rep = rVec
  87. instance (Rep a, Rep n, Sat (ctx a)) => Rep1 ctx (Vec a n) where
  88. rep1 = rVec1