2018-03-30 00:35:12 +02:00
|
|
|
{-# LANGUAGE CPP #-}
|
2018-03-31 23:43:08 +02:00
|
|
|
{-# LANGUAGE MultiParamTypeClasses #-}
|
2018-04-02 07:49:12 +02:00
|
|
|
{-# LANGUAGE RankNTypes #-}
|
2018-03-30 10:11:27 +02:00
|
|
|
{-# LANGUAGE ScopedTypeVariables #-}
|
2018-03-30 00:35:12 +02:00
|
|
|
|
|
|
|
module Nix.Utils (module Nix.Utils, module X) where
|
2018-03-29 00:00:28 +02:00
|
|
|
|
2018-03-31 23:43:08 +02:00
|
|
|
import Control.Applicative
|
2018-03-29 00:00:28 +02:00
|
|
|
import Control.Monad
|
2018-03-30 00:35:12 +02:00
|
|
|
import Control.Monad.Fix
|
2018-03-29 00:00:28 +02:00
|
|
|
import Data.Fix
|
2018-03-31 23:43:08 +02:00
|
|
|
import Data.Functor.Identity
|
2018-03-30 23:08:38 +02:00
|
|
|
import Data.Monoid (Endo)
|
2018-03-29 00:00:28 +02:00
|
|
|
|
2018-04-03 07:49:21 +02:00
|
|
|
-- #define ENABLE_TRACING 1
|
2018-03-30 00:35:12 +02:00
|
|
|
#if ENABLE_TRACING
|
|
|
|
import Debug.Trace as X
|
|
|
|
#else
|
|
|
|
import Prelude as X
|
|
|
|
trace :: String -> a -> a
|
|
|
|
trace = const id
|
|
|
|
traceM :: Monad m => String -> m ()
|
|
|
|
traceM = const (return ())
|
|
|
|
#endif
|
|
|
|
|
2018-03-30 22:30:28 +02:00
|
|
|
type DList a = Endo [a]
|
|
|
|
|
2018-03-29 00:00:28 +02:00
|
|
|
(&) :: a -> (a -> c) -> c
|
|
|
|
(&) = flip ($)
|
|
|
|
|
2018-04-01 06:05:48 +02:00
|
|
|
(<&>) :: Functor f => f a -> (a -> c) -> f c
|
|
|
|
(<&>) = flip (<$>)
|
|
|
|
|
2018-04-03 06:50:38 +02:00
|
|
|
(??) :: Functor f => f (a -> b) -> a -> f b
|
|
|
|
fab ?? a = fmap ($ a) fab
|
|
|
|
|
2018-03-29 00:00:28 +02:00
|
|
|
loeb :: Functor f => f (f a -> a) -> f a
|
|
|
|
loeb x = go where go = fmap ($ go) x
|
|
|
|
|
2018-03-30 00:35:12 +02:00
|
|
|
loebM :: (MonadFix m, Traversable t) => t (t a -> m a) -> m (t a)
|
|
|
|
loebM f = mfix $ \a -> mapM ($ a) f
|
|
|
|
|
2018-03-30 22:18:24 +02:00
|
|
|
para :: (a -> [a] -> b -> b) -> b -> [a] -> b
|
|
|
|
para f base = h where
|
|
|
|
h [] = base
|
|
|
|
h (x:xs) = f x xs (h xs)
|
|
|
|
|
2018-04-03 06:44:01 +02:00
|
|
|
paraM :: Monad m => (a -> [a] -> b -> m b) -> b -> [a] -> m b
|
|
|
|
paraM f base = h where
|
|
|
|
h [] = return base
|
|
|
|
h (x:xs) = f x xs =<< h xs
|
|
|
|
|
2018-03-29 00:00:28 +02:00
|
|
|
-- | adi is Abstracting Definitional Interpreters:
|
|
|
|
--
|
|
|
|
-- https://arxiv.org/abs/1707.04755
|
|
|
|
--
|
|
|
|
-- Essentially, it does for evaluation what recursion schemes do for
|
|
|
|
-- representation: allows threading layers through existing structure, only
|
|
|
|
-- in this case through behavior.
|
2018-03-31 08:34:57 +02:00
|
|
|
adi :: Traversable t
|
2018-03-29 00:00:28 +02:00
|
|
|
=> (t a -> a)
|
2018-03-31 08:34:57 +02:00
|
|
|
-> ((Fix t -> a) -> Fix t -> a)
|
|
|
|
-> Fix t -> a
|
|
|
|
adi f g = g (f . fmap (adi f g) . unFix)
|
2018-03-29 00:00:28 +02:00
|
|
|
|
2018-03-31 08:34:57 +02:00
|
|
|
adiM :: (Traversable t, Monad m)
|
2018-03-29 00:00:28 +02:00
|
|
|
=> (t a -> m a)
|
2018-03-31 08:34:57 +02:00
|
|
|
-> ((Fix t -> m a) -> Fix t -> m a)
|
|
|
|
-> Fix t -> m a
|
|
|
|
adiM f g = g ((f <=< traverse (adiM f g)) . unFix)
|
2018-03-31 23:43:08 +02:00
|
|
|
|
|
|
|
type MonoLens a b = forall f. Functor f => (b -> f b) -> a -> f a
|
|
|
|
|
|
|
|
view :: MonoLens a b -> a -> b
|
|
|
|
view l = getConst . l Const
|
|
|
|
|
|
|
|
set :: MonoLens a b -> b -> a -> a
|
|
|
|
set l b = runIdentity . l (\_ -> Identity b)
|
|
|
|
|
|
|
|
over :: MonoLens a b -> (b -> b) -> a -> a
|
|
|
|
over l f = runIdentity . l (Identity . f)
|
|
|
|
|
|
|
|
class Has a b where
|
|
|
|
hasLens :: MonoLens a b
|