{-# LANGUAGE Rank2Types #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE FlexibleContexts #-} {- | An alternative Shape class that allows to add new \"methods\", but forbids to add new instances. You can provide new \"methods\" by calling 'switch' with a newtype around your function type. For the general concept, see: <https://www.haskell.org/haskellwiki/Closed_world_instances> -} module Data.Array.Accelerate.Utility.Shape ( C(..), ) where import qualified Data.Array.Accelerate as A import Data.Array.Accelerate (Exp, Z, (:.)) class (A.Shape sh, A.Slice sh, A.Elt sh, Eq sh, A.Plain sh ~ sh, A.Lift Exp sh) => C sh where switch :: f Z -> (forall sh0. C sh0 => f (sh0 :. Int)) -> f sh instance C Z where switch f _ = f instance (C sh, i ~ Int) => C (sh:.i) where switch _ f = f