{-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} module Interpreter.Rep where import Data.IORef import GHC.TypeError import Array import AST type family Rep t where Rep TNil = () Rep (TPair a b) = (Rep a, Rep b) Rep (TEither a b) = Either (Rep a) (Rep b) Rep (TMaybe t) = Maybe (Rep t) Rep (TArr n t) = Array n (Rep t) Rep (TScal sty) = ScalRep sty Rep (TAccum t) = RepAcSparse t -- Mutable, and has a zero. The zero may not be O(1), but RepAcSparse (D2 t) will have an O(1) zero. type family RepAcSparse t where RepAcSparse TNil = () RepAcSparse (TPair a b) = IORef (RepAcDense (TPair a b)) RepAcSparse (TEither a b) = TypeError (Text "Non-sparse coproduct is not a monoid") RepAcSparse (TMaybe t) = IORef (Maybe (RepAcDense t)) -- allow the value to be dense, because the Maybe's zero can be used for the contents RepAcSparse (TArr n t) = IORef (RepAcDense (TArr n t)) -- empty array is zero RepAcSparse (TScal sty) = IORef (ScalRep sty) RepAcSparse (TAccum t) = TypeError (Text "RepAcSparse: Nested accumulators") -- Immutable, and does not necessarily have a zero. type family RepAcDense t where RepAcDense TNil = () RepAcDense (TPair a b) = (RepAcSparse a, RepAcSparse b) RepAcDense (TEither a b) = Either (RepAcSparse a) (RepAcSparse b) RepAcDense (TMaybe t) = Maybe (RepAcSparse t) RepAcDense (TArr n t) = Array n (RepAcSparse t) RepAcDense (TScal sty) = ScalRep sty RepAcDense (TAccum t) = TypeError (Text "RepAcDense: Nested accumulators")