{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TemplateHaskell #-}

{-# OPTIONS_GHC -Wno-missing-signatures #-}

module Nix.Cited where

import           Control.Comonad
import           Control.Comonad.Env
import           Data.Typeable                  ( Typeable )
import           GHC.Generics
import           Lens.Family2.TH

import           Nix.Expr.Types.Annotated
import           Nix.Scope

data Provenance m v = Provenance
    { Provenance m v -> Scopes m v
_lexicalScope :: Scopes m v
    , Provenance m v -> NExprLocF (Maybe v)
_originExpr   :: NExprLocF (Maybe v)
      -- ^ When calling the function x: x + 2 with argument x = 3, the
      --   'originExpr' for the resulting value will be 3 + 2, while the
      --   'contextExpr' will be @(x: x + 2) 3@, preserving not only the
      --   result of the call, but what was called and with what arguments.
    }
    deriving ((forall x. Provenance m v -> Rep (Provenance m v) x)
-> (forall x. Rep (Provenance m v) x -> Provenance m v)
-> Generic (Provenance m v)
forall x. Rep (Provenance m v) x -> Provenance m v
forall x. Provenance m v -> Rep (Provenance m v) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (m :: * -> *) v x. Rep (Provenance m v) x -> Provenance m v
forall (m :: * -> *) v x. Provenance m v -> Rep (Provenance m v) x
$cto :: forall (m :: * -> *) v x. Rep (Provenance m v) x -> Provenance m v
$cfrom :: forall (m :: * -> *) v x. Provenance m v -> Rep (Provenance m v) x
Generic, Typeable, Int -> Provenance m v -> ShowS
[Provenance m v] -> ShowS
Provenance m v -> String
(Int -> Provenance m v -> ShowS)
-> (Provenance m v -> String)
-> ([Provenance m v] -> ShowS)
-> Show (Provenance m v)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (m :: * -> *) v. Show v => Int -> Provenance m v -> ShowS
forall (m :: * -> *) v. Show v => [Provenance m v] -> ShowS
forall (m :: * -> *) v. Show v => Provenance m v -> String
showList :: [Provenance m v] -> ShowS
$cshowList :: forall (m :: * -> *) v. Show v => [Provenance m v] -> ShowS
show :: Provenance m v -> String
$cshow :: forall (m :: * -> *) v. Show v => Provenance m v -> String
showsPrec :: Int -> Provenance m v -> ShowS
$cshowsPrec :: forall (m :: * -> *) v. Show v => Int -> Provenance m v -> ShowS
Show)

data NCited m v a = NCited
    { NCited m v a -> [Provenance m v]
_provenance :: [Provenance m v]
    , NCited m v a -> a
_cited      :: a
    }
    deriving ((forall x. NCited m v a -> Rep (NCited m v a) x)
-> (forall x. Rep (NCited m v a) x -> NCited m v a)
-> Generic (NCited m v a)
forall x. Rep (NCited m v a) x -> NCited m v a
forall x. NCited m v a -> Rep (NCited m v a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (m :: * -> *) v a x. Rep (NCited m v a) x -> NCited m v a
forall (m :: * -> *) v a x. NCited m v a -> Rep (NCited m v a) x
$cto :: forall (m :: * -> *) v a x. Rep (NCited m v a) x -> NCited m v a
$cfrom :: forall (m :: * -> *) v a x. NCited m v a -> Rep (NCited m v a) x
Generic, Typeable, a -> NCited m v b -> NCited m v a
(a -> b) -> NCited m v a -> NCited m v b
(forall a b. (a -> b) -> NCited m v a -> NCited m v b)
-> (forall a b. a -> NCited m v b -> NCited m v a)
-> Functor (NCited m v)
forall a b. a -> NCited m v b -> NCited m v a
forall a b. (a -> b) -> NCited m v a -> NCited m v b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
forall (m :: * -> *) v a b. a -> NCited m v b -> NCited m v a
forall (m :: * -> *) v a b.
(a -> b) -> NCited m v a -> NCited m v b
<$ :: a -> NCited m v b -> NCited m v a
$c<$ :: forall (m :: * -> *) v a b. a -> NCited m v b -> NCited m v a
fmap :: (a -> b) -> NCited m v a -> NCited m v b
$cfmap :: forall (m :: * -> *) v a b.
(a -> b) -> NCited m v a -> NCited m v b
Functor, NCited m v a -> Bool
(a -> m) -> NCited m v a -> m
(a -> b -> b) -> b -> NCited m v a -> b
(forall m. Monoid m => NCited m v m -> m)
-> (forall m a. Monoid m => (a -> m) -> NCited m v a -> m)
-> (forall m a. Monoid m => (a -> m) -> NCited m v a -> m)
-> (forall a b. (a -> b -> b) -> b -> NCited m v a -> b)
-> (forall a b. (a -> b -> b) -> b -> NCited m v a -> b)
-> (forall b a. (b -> a -> b) -> b -> NCited m v a -> b)
-> (forall b a. (b -> a -> b) -> b -> NCited m v a -> b)
-> (forall a. (a -> a -> a) -> NCited m v a -> a)
-> (forall a. (a -> a -> a) -> NCited m v a -> a)
-> (forall a. NCited m v a -> [a])
-> (forall a. NCited m v a -> Bool)
-> (forall a. NCited m v a -> Int)
-> (forall a. Eq a => a -> NCited m v a -> Bool)
-> (forall a. Ord a => NCited m v a -> a)
-> (forall a. Ord a => NCited m v a -> a)
-> (forall a. Num a => NCited m v a -> a)
-> (forall a. Num a => NCited m v a -> a)
-> Foldable (NCited m v)
forall a. Eq a => a -> NCited m v a -> Bool
forall a. Num a => NCited m v a -> a
forall a. Ord a => NCited m v a -> a
forall m. Monoid m => NCited m v m -> m
forall a. NCited m v a -> Bool
forall a. NCited m v a -> Int
forall a. NCited m v a -> [a]
forall a. (a -> a -> a) -> NCited m v a -> a
forall m a. Monoid m => (a -> m) -> NCited m v a -> m
forall b a. (b -> a -> b) -> b -> NCited m v a -> b
forall a b. (a -> b -> b) -> b -> NCited m v a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
forall (m :: * -> *) v a. Eq a => a -> NCited m v a -> Bool
forall (m :: * -> *) v a. Num a => NCited m v a -> a
forall (m :: * -> *) v a. Ord a => NCited m v a -> a
forall (m :: * -> *) v m. Monoid m => NCited m v m -> m
forall (m :: * -> *) v a. NCited m v a -> Bool
forall (m :: * -> *) v a. NCited m v a -> Int
forall (m :: * -> *) v a. NCited m v a -> [a]
forall (m :: * -> *) v a. (a -> a -> a) -> NCited m v a -> a
forall (m :: * -> *) v m a.
Monoid m =>
(a -> m) -> NCited m v a -> m
forall (m :: * -> *) v b a. (b -> a -> b) -> b -> NCited m v a -> b
forall (m :: * -> *) v a b. (a -> b -> b) -> b -> NCited m v a -> b
product :: NCited m v a -> a
$cproduct :: forall (m :: * -> *) v a. Num a => NCited m v a -> a
sum :: NCited m v a -> a
$csum :: forall (m :: * -> *) v a. Num a => NCited m v a -> a
minimum :: NCited m v a -> a
$cminimum :: forall (m :: * -> *) v a. Ord a => NCited m v a -> a
maximum :: NCited m v a -> a
$cmaximum :: forall (m :: * -> *) v a. Ord a => NCited m v a -> a
elem :: a -> NCited m v a -> Bool
$celem :: forall (m :: * -> *) v a. Eq a => a -> NCited m v a -> Bool
length :: NCited m v a -> Int
$clength :: forall (m :: * -> *) v a. NCited m v a -> Int
null :: NCited m v a -> Bool
$cnull :: forall (m :: * -> *) v a. NCited m v a -> Bool
toList :: NCited m v a -> [a]
$ctoList :: forall (m :: * -> *) v a. NCited m v a -> [a]
foldl1 :: (a -> a -> a) -> NCited m v a -> a
$cfoldl1 :: forall (m :: * -> *) v a. (a -> a -> a) -> NCited m v a -> a
foldr1 :: (a -> a -> a) -> NCited m v a -> a
$cfoldr1 :: forall (m :: * -> *) v a. (a -> a -> a) -> NCited m v a -> a
foldl' :: (b -> a -> b) -> b -> NCited m v a -> b
$cfoldl' :: forall (m :: * -> *) v b a. (b -> a -> b) -> b -> NCited m v a -> b
foldl :: (b -> a -> b) -> b -> NCited m v a -> b
$cfoldl :: forall (m :: * -> *) v b a. (b -> a -> b) -> b -> NCited m v a -> b
foldr' :: (a -> b -> b) -> b -> NCited m v a -> b
$cfoldr' :: forall (m :: * -> *) v a b. (a -> b -> b) -> b -> NCited m v a -> b
foldr :: (a -> b -> b) -> b -> NCited m v a -> b
$cfoldr :: forall (m :: * -> *) v a b. (a -> b -> b) -> b -> NCited m v a -> b
foldMap' :: (a -> m) -> NCited m v a -> m
$cfoldMap' :: forall (m :: * -> *) v m a.
Monoid m =>
(a -> m) -> NCited m v a -> m
foldMap :: (a -> m) -> NCited m v a -> m
$cfoldMap :: forall (m :: * -> *) v m a.
Monoid m =>
(a -> m) -> NCited m v a -> m
fold :: NCited m v m -> m
$cfold :: forall (m :: * -> *) v m. Monoid m => NCited m v m -> m
Foldable, Functor (NCited m v)
Foldable (NCited m v)
(Functor (NCited m v), Foldable (NCited m v)) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> NCited m v a -> f (NCited m v b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    NCited m v (f a) -> f (NCited m v a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> NCited m v a -> m (NCited m v b))
-> (forall (m :: * -> *) a.
    Monad m =>
    NCited m v (m a) -> m (NCited m v a))
-> Traversable (NCited m v)
(a -> f b) -> NCited m v a -> f (NCited m v b)
forall (t :: * -> *).
(Functor t, Foldable t) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) v. Functor (NCited m v)
forall (m :: * -> *) v. Foldable (NCited m v)
forall (m :: * -> *) a.
Monad m =>
NCited m v (m a) -> m (NCited m v a)
forall (f :: * -> *) a.
Applicative f =>
NCited m v (f a) -> f (NCited m v a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> NCited m v a -> m (NCited m v b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> NCited m v a -> f (NCited m v b)
forall (m :: * -> *) v (m :: * -> *) a.
Monad m =>
NCited m v (m a) -> m (NCited m v a)
forall (m :: * -> *) v (f :: * -> *) a.
Applicative f =>
NCited m v (f a) -> f (NCited m v a)
forall (m :: * -> *) v (m :: * -> *) a b.
Monad m =>
(a -> m b) -> NCited m v a -> m (NCited m v b)
forall (m :: * -> *) v (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> NCited m v a -> f (NCited m v b)
sequence :: NCited m v (m a) -> m (NCited m v a)
$csequence :: forall (m :: * -> *) v (m :: * -> *) a.
Monad m =>
NCited m v (m a) -> m (NCited m v a)
mapM :: (a -> m b) -> NCited m v a -> m (NCited m v b)
$cmapM :: forall (m :: * -> *) v (m :: * -> *) a b.
Monad m =>
(a -> m b) -> NCited m v a -> m (NCited m v b)
sequenceA :: NCited m v (f a) -> f (NCited m v a)
$csequenceA :: forall (m :: * -> *) v (f :: * -> *) a.
Applicative f =>
NCited m v (f a) -> f (NCited m v a)
traverse :: (a -> f b) -> NCited m v a -> f (NCited m v b)
$ctraverse :: forall (m :: * -> *) v (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> NCited m v a -> f (NCited m v b)
$cp2Traversable :: forall (m :: * -> *) v. Foldable (NCited m v)
$cp1Traversable :: forall (m :: * -> *) v. Functor (NCited m v)
Traversable, Int -> NCited m v a -> ShowS
[NCited m v a] -> ShowS
NCited m v a -> String
(Int -> NCited m v a -> ShowS)
-> (NCited m v a -> String)
-> ([NCited m v a] -> ShowS)
-> Show (NCited m v a)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (m :: * -> *) v a.
(Show v, Show a) =>
Int -> NCited m v a -> ShowS
forall (m :: * -> *) v a.
(Show v, Show a) =>
[NCited m v a] -> ShowS
forall (m :: * -> *) v a.
(Show v, Show a) =>
NCited m v a -> String
showList :: [NCited m v a] -> ShowS
$cshowList :: forall (m :: * -> *) v a.
(Show v, Show a) =>
[NCited m v a] -> ShowS
show :: NCited m v a -> String
$cshow :: forall (m :: * -> *) v a.
(Show v, Show a) =>
NCited m v a -> String
showsPrec :: Int -> NCited m v a -> ShowS
$cshowsPrec :: forall (m :: * -> *) v a.
(Show v, Show a) =>
Int -> NCited m v a -> ShowS
Show)

instance Applicative (NCited m v) where
  pure :: a -> NCited m v a
pure = [Provenance m v] -> a -> NCited m v a
forall (m :: * -> *) v a. [Provenance m v] -> a -> NCited m v a
NCited []
  NCited xs :: [Provenance m v]
xs f :: a -> b
f <*> :: NCited m v (a -> b) -> NCited m v a -> NCited m v b
<*> NCited ys :: [Provenance m v]
ys x :: a
x = [Provenance m v] -> b -> NCited m v b
forall (m :: * -> *) v a. [Provenance m v] -> a -> NCited m v a
NCited ([Provenance m v]
xs [Provenance m v] -> [Provenance m v] -> [Provenance m v]
forall a. Semigroup a => a -> a -> a
<> [Provenance m v]
ys) (a -> b
f a
x)

instance Comonad (NCited m v) where
  duplicate :: NCited m v a -> NCited m v (NCited m v a)
duplicate p :: NCited m v a
p = [Provenance m v] -> NCited m v a -> NCited m v (NCited m v a)
forall (m :: * -> *) v a. [Provenance m v] -> a -> NCited m v a
NCited (NCited m v a -> [Provenance m v]
forall (m :: * -> *) v a. NCited m v a -> [Provenance m v]
_provenance NCited m v a
p) NCited m v a
p
  extract :: NCited m v a -> a
extract = NCited m v a -> a
forall (m :: * -> *) v a. NCited m v a -> a
_cited

instance ComonadEnv [Provenance m v] (NCited m v) where
  ask :: NCited m v a -> [Provenance m v]
ask = NCited m v a -> [Provenance m v]
forall (m :: * -> *) v a. NCited m v a -> [Provenance m v]
_provenance

$(makeLenses ''Provenance)
$(makeLenses ''NCited)

class HasCitations m v a where
    citations :: a -> [Provenance m v]
    addProvenance :: Provenance m v -> a -> a

instance HasCitations m v (NCited m v a) where
  citations :: NCited m v a -> [Provenance m v]
citations = NCited m v a -> [Provenance m v]
forall (m :: * -> *) v a. NCited m v a -> [Provenance m v]
_provenance
  addProvenance :: Provenance m v -> NCited m v a -> NCited m v a
addProvenance x :: Provenance m v
x (NCited p :: [Provenance m v]
p v :: a
v) = ([Provenance m v] -> a -> NCited m v a
forall (m :: * -> *) v a. [Provenance m v] -> a -> NCited m v a
NCited (Provenance m v
x Provenance m v -> [Provenance m v] -> [Provenance m v]
forall a. a -> [a] -> [a]
: [Provenance m v]
p) a
v)

class HasCitations1 m v f where
    citations1 :: f a -> [Provenance m v]
    addProvenance1 :: Provenance m v -> f a -> f a