grisette-0.1.0.0: src/Grisette/IR/SymPrim/Data/TabularFun.hs
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveLift #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
-- |
-- Module : Grisette.IR.SymPrim.Data.TabularFun
-- Copyright : (c) Sirui Lu 2021-2023
-- License : BSD-3-Clause (see the LICENSE file)
--
-- Maintainer : siruilu@cs.washington.edu
-- Stability : Experimental
-- Portability : GHC only
module Grisette.IR.SymPrim.Data.TabularFun
( type (=->) (..),
)
where
import Control.DeepSeq
import Data.Hashable
import GHC.Generics
import Grisette.Core.Data.Class.Function
import Grisette.IR.SymPrim.Data.Prim.InternedTerm.Term
import Language.Haskell.TH.Syntax
-- $setup
-- >>> import Grisette.Core
-- >>> import Grisette.IR.SymPrim
-- |
-- Functions as a table. Use the `#` operator to apply the function.
--
-- >>> :set -XTypeOperators
-- >>> let f = TabularFun [(1, 2), (3, 4)] 0 :: Int =-> Int
-- >>> f # 1
-- 2
-- >>> f # 2
-- 0
-- >>> f # 3
-- 4
data (=->) a b = TabularFun {funcTable :: [(a, b)], defaultFuncValue :: b}
deriving (Show, Eq, Generic, Generic1, Lift, NFData, NFData1)
infixr 0 =->
instance
(SupportedPrim a, SupportedPrim b) =>
SupportedPrim (a =-> b)
where
type PrimConstraint (a =-> b) = (SupportedPrim a, SupportedPrim b)
defaultValue = TabularFun [] (defaultValue @b)
instance (Eq a) => Function (a =-> b) where
type Arg (a =-> b) = a
type Ret (a =-> b) = b
(TabularFun table d) # a = go table
where
go [] = d
go ((av, bv) : s)
| a == av = bv
| otherwise = go s
instance (Hashable a, Hashable b) => Hashable (a =-> b)