{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeApplications #-}
module Datafix.Worklist.Denotational
( evalDenotation
) where
import Datafix.Common
import Datafix.Denotational
import Datafix.Entailments
import Datafix.Utils.Constraints
import Datafix.Utils.TypeLevel
import Datafix.FrameworkBuilder
import qualified Datafix.Worklist.Graph.Dense as DenseGraph
import Datafix.Worklist.Internal
import Data.Type.Equality
evalDenotation
:: forall domain func
. Datafixable domain
=> Forall (Currying (ParamTypes func))
=> Denotation domain func
-> IterationBound domain
-> func
evalDenotation plan ib =
castWith arrowsAxiom (currys @(ParamTypes func) @(ReturnType func) impl \\ idInst @func)
where
impl :: Products (ParamTypes func) -> ReturnType func
impl args = solveProblem prob (Dense max_) ib (uncurriedDenot args)
uncurriedDenot = uncurrys @(ParamTypes func) denot \\ lfInst @func @(DependencyM DenseGraph.Ref domain)
(denot, max_, prob) = buildFramework plan
{-# INLINE evalDenotation #-}