summaryrefslogtreecommitdiff
path: root/src/Interpreter/Rep.hs
blob: 680196c83f20c56213459d430b5ec8230cd5967f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
{-# 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 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")