{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}

module Algebra.Morphism.LinComb where

import Prelude hiding (Num(..), sum)
-- import Data.List (intercalate,and,filter)
import Algebra.Classes
import qualified Data.Map as M
-- import Data.Function (on)
-- import Data.Monoid
-- import Control.Applicative
-- import Data.Traversable

-- | Normalised linear combinations as maps from variables to
-- coefficients (zero coefficient never present in the map)
newtype LinComb x c = LinComb (M.Map x c)
  deriving ((forall a b. (a -> b) -> LinComb x a -> LinComb x b)
-> (forall a b. a -> LinComb x b -> LinComb x a)
-> Functor (LinComb x)
forall a b. a -> LinComb x b -> LinComb x a
forall a b. (a -> b) -> LinComb x a -> LinComb x b
forall x a b. a -> LinComb x b -> LinComb x a
forall x a b. (a -> b) -> LinComb x a -> LinComb x b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall x a b. (a -> b) -> LinComb x a -> LinComb x b
fmap :: forall a b. (a -> b) -> LinComb x a -> LinComb x b
$c<$ :: forall x a b. a -> LinComb x b -> LinComb x a
<$ :: forall a b. a -> LinComb x b -> LinComb x a
Functor,Additive (LinComb x c)
Additive (LinComb x c) => AbelianAdditive (LinComb x c)
forall a. Additive a => AbelianAdditive a
forall x c.
(AbelianAdditive c, DecidableZero c, Ord x) =>
Additive (LinComb x c)
AbelianAdditive,LinComb x c -> LinComb x c -> Bool
(LinComb x c -> LinComb x c -> Bool)
-> (LinComb x c -> LinComb x c -> Bool) -> Eq (LinComb x c)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall x c. (Eq x, Eq c) => LinComb x c -> LinComb x c -> Bool
$c== :: forall x c. (Eq x, Eq c) => LinComb x c -> LinComb x c -> Bool
== :: LinComb x c -> LinComb x c -> Bool
$c/= :: forall x c. (Eq x, Eq c) => LinComb x c -> LinComb x c -> Bool
/= :: LinComb x c -> LinComb x c -> Bool
Eq,Eq (LinComb x c)
Eq (LinComb x c) =>
(LinComb x c -> LinComb x c -> Ordering)
-> (LinComb x c -> LinComb x c -> Bool)
-> (LinComb x c -> LinComb x c -> Bool)
-> (LinComb x c -> LinComb x c -> Bool)
-> (LinComb x c -> LinComb x c -> Bool)
-> (LinComb x c -> LinComb x c -> LinComb x c)
-> (LinComb x c -> LinComb x c -> LinComb x c)
-> Ord (LinComb x c)
LinComb x c -> LinComb x c -> Bool
LinComb x c -> LinComb x c -> Ordering
LinComb x c -> LinComb x c -> LinComb x c
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall x c. (Ord x, Ord c) => Eq (LinComb x c)
forall x c. (Ord x, Ord c) => LinComb x c -> LinComb x c -> Bool
forall x c.
(Ord x, Ord c) =>
LinComb x c -> LinComb x c -> Ordering
forall x c.
(Ord x, Ord c) =>
LinComb x c -> LinComb x c -> LinComb x c
$ccompare :: forall x c.
(Ord x, Ord c) =>
LinComb x c -> LinComb x c -> Ordering
compare :: LinComb x c -> LinComb x c -> Ordering
$c< :: forall x c. (Ord x, Ord c) => LinComb x c -> LinComb x c -> Bool
< :: LinComb x c -> LinComb x c -> Bool
$c<= :: forall x c. (Ord x, Ord c) => LinComb x c -> LinComb x c -> Bool
<= :: LinComb x c -> LinComb x c -> Bool
$c> :: forall x c. (Ord x, Ord c) => LinComb x c -> LinComb x c -> Bool
> :: LinComb x c -> LinComb x c -> Bool
$c>= :: forall x c. (Ord x, Ord c) => LinComb x c -> LinComb x c -> Bool
>= :: LinComb x c -> LinComb x c -> Bool
$cmax :: forall x c.
(Ord x, Ord c) =>
LinComb x c -> LinComb x c -> LinComb x c
max :: LinComb x c -> LinComb x c -> LinComb x c
$cmin :: forall x c.
(Ord x, Ord c) =>
LinComb x c -> LinComb x c -> LinComb x c
min :: LinComb x c -> LinComb x c -> LinComb x c
Ord,Int -> LinComb x c -> ShowS
[LinComb x c] -> ShowS
LinComb x c -> String
(Int -> LinComb x c -> ShowS)
-> (LinComb x c -> String)
-> ([LinComb x c] -> ShowS)
-> Show (LinComb x c)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall x c. (Show x, Show c) => Int -> LinComb x c -> ShowS
forall x c. (Show x, Show c) => [LinComb x c] -> ShowS
forall x c. (Show x, Show c) => LinComb x c -> String
$cshowsPrec :: forall x c. (Show x, Show c) => Int -> LinComb x c -> ShowS
showsPrec :: Int -> LinComb x c -> ShowS
$cshow :: forall x c. (Show x, Show c) => LinComb x c -> String
show :: LinComb x c -> String
$cshowList :: forall x c. (Show x, Show c) => [LinComb x c] -> ShowS
showList :: [LinComb x c] -> ShowS
Show,Functor (LinComb x)
Foldable (LinComb x)
(Functor (LinComb x), Foldable (LinComb x)) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> LinComb x a -> f (LinComb x b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    LinComb x (f a) -> f (LinComb x a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> LinComb x a -> m (LinComb x b))
-> (forall (m :: * -> *) a.
    Monad m =>
    LinComb x (m a) -> m (LinComb x a))
-> Traversable (LinComb x)
forall x. Functor (LinComb x)
forall x. Foldable (LinComb x)
forall x (m :: * -> *) a.
Monad m =>
LinComb x (m a) -> m (LinComb x a)
forall x (f :: * -> *) a.
Applicative f =>
LinComb x (f a) -> f (LinComb x a)
forall x (m :: * -> *) a b.
Monad m =>
(a -> m b) -> LinComb x a -> m (LinComb x b)
forall x (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> LinComb x a -> f (LinComb x 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 :: * -> *) a.
Monad m =>
LinComb x (m a) -> m (LinComb x a)
forall (f :: * -> *) a.
Applicative f =>
LinComb x (f a) -> f (LinComb x a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> LinComb x a -> m (LinComb x b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> LinComb x a -> f (LinComb x b)
$ctraverse :: forall x (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> LinComb x a -> f (LinComb x b)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> LinComb x a -> f (LinComb x b)
$csequenceA :: forall x (f :: * -> *) a.
Applicative f =>
LinComb x (f a) -> f (LinComb x a)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
LinComb x (f a) -> f (LinComb x a)
$cmapM :: forall x (m :: * -> *) a b.
Monad m =>
(a -> m b) -> LinComb x a -> m (LinComb x b)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> LinComb x a -> m (LinComb x b)
$csequence :: forall x (m :: * -> *) a.
Monad m =>
LinComb x (m a) -> m (LinComb x a)
sequence :: forall (m :: * -> *) a.
Monad m =>
LinComb x (m a) -> m (LinComb x a)
Traversable,(forall m. Monoid m => LinComb x m -> m)
-> (forall m a. Monoid m => (a -> m) -> LinComb x a -> m)
-> (forall m a. Monoid m => (a -> m) -> LinComb x a -> m)
-> (forall a b. (a -> b -> b) -> b -> LinComb x a -> b)
-> (forall a b. (a -> b -> b) -> b -> LinComb x a -> b)
-> (forall b a. (b -> a -> b) -> b -> LinComb x a -> b)
-> (forall b a. (b -> a -> b) -> b -> LinComb x a -> b)
-> (forall a. (a -> a -> a) -> LinComb x a -> a)
-> (forall a. (a -> a -> a) -> LinComb x a -> a)
-> (forall a. LinComb x a -> [a])
-> (forall a. LinComb x a -> Bool)
-> (forall a. LinComb x a -> Int)
-> (forall a. Eq a => a -> LinComb x a -> Bool)
-> (forall a. Ord a => LinComb x a -> a)
-> (forall a. Ord a => LinComb x a -> a)
-> (forall a. Num a => LinComb x a -> a)
-> (forall a. Num a => LinComb x a -> a)
-> Foldable (LinComb x)
forall a. Eq a => a -> LinComb x a -> Bool
forall a. Num a => LinComb x a -> a
forall a. Ord a => LinComb x a -> a
forall m. Monoid m => LinComb x m -> m
forall a. LinComb x a -> Bool
forall a. LinComb x a -> Int
forall a. LinComb x a -> [a]
forall a. (a -> a -> a) -> LinComb x a -> a
forall x a. Eq a => a -> LinComb x a -> Bool
forall x a. Num a => LinComb x a -> a
forall x a. Ord a => LinComb x a -> a
forall m a. Monoid m => (a -> m) -> LinComb x a -> m
forall x m. Monoid m => LinComb x m -> m
forall x a. LinComb x a -> Bool
forall x a. LinComb x a -> Int
forall x a. LinComb x a -> [a]
forall b a. (b -> a -> b) -> b -> LinComb x a -> b
forall a b. (a -> b -> b) -> b -> LinComb x a -> b
forall x a. (a -> a -> a) -> LinComb x a -> a
forall x m a. Monoid m => (a -> m) -> LinComb x a -> m
forall x b a. (b -> a -> b) -> b -> LinComb x a -> b
forall x a b. (a -> b -> b) -> b -> LinComb x 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
$cfold :: forall x m. Monoid m => LinComb x m -> m
fold :: forall m. Monoid m => LinComb x m -> m
$cfoldMap :: forall x m a. Monoid m => (a -> m) -> LinComb x a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> LinComb x a -> m
$cfoldMap' :: forall x m a. Monoid m => (a -> m) -> LinComb x a -> m
foldMap' :: forall m a. Monoid m => (a -> m) -> LinComb x a -> m
$cfoldr :: forall x a b. (a -> b -> b) -> b -> LinComb x a -> b
foldr :: forall a b. (a -> b -> b) -> b -> LinComb x a -> b
$cfoldr' :: forall x a b. (a -> b -> b) -> b -> LinComb x a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> LinComb x a -> b
$cfoldl :: forall x b a. (b -> a -> b) -> b -> LinComb x a -> b
foldl :: forall b a. (b -> a -> b) -> b -> LinComb x a -> b
$cfoldl' :: forall x b a. (b -> a -> b) -> b -> LinComb x a -> b
foldl' :: forall b a. (b -> a -> b) -> b -> LinComb x a -> b
$cfoldr1 :: forall x a. (a -> a -> a) -> LinComb x a -> a
foldr1 :: forall a. (a -> a -> a) -> LinComb x a -> a
$cfoldl1 :: forall x a. (a -> a -> a) -> LinComb x a -> a
foldl1 :: forall a. (a -> a -> a) -> LinComb x a -> a
$ctoList :: forall x a. LinComb x a -> [a]
toList :: forall a. LinComb x a -> [a]
$cnull :: forall x a. LinComb x a -> Bool
null :: forall a. LinComb x a -> Bool
$clength :: forall x a. LinComb x a -> Int
length :: forall a. LinComb x a -> Int
$celem :: forall x a. Eq a => a -> LinComb x a -> Bool
elem :: forall a. Eq a => a -> LinComb x a -> Bool
$cmaximum :: forall x a. Ord a => LinComb x a -> a
maximum :: forall a. Ord a => LinComb x a -> a
$cminimum :: forall x a. Ord a => LinComb x a -> a
minimum :: forall a. Ord a => LinComb x a -> a
$csum :: forall x a. Num a => LinComb x a -> a
sum :: forall a. Num a => LinComb x a -> a
$cproduct :: forall x a. Num a => LinComb x a -> a
product :: forall a. Num a => LinComb x a -> a
Foldable)
deriving instance {-# Overlappable #-} Scalable s a => Scalable s (LinComb k a)

fromLinComb :: LinComb x c -> M.Map x c
fromLinComb :: forall x c. LinComb x c -> Map x c
fromLinComb (LinComb Map x c
x) = Map x c
x
eval :: forall d x c v. Scalable d x => Additive x => (c -> d) -> (v -> x) -> LinComb v c -> x
eval :: forall d x c v.
(Scalable d x, Additive x) =>
(c -> d) -> (v -> x) -> LinComb v c -> x
eval c -> d
fc v -> x
fv LinComb v c
p = [x] -> x
forall (t :: * -> *) a. (Foldable t, Additive a) => t a -> a
sum [ c -> d
fc c
c d -> x -> x
forall s a. Scalable s a => s -> a -> a
*^ v -> x
fv v
v | (v
v, c
c) <- LinComb v c -> [(v, c)]
forall k a. LinComb k a -> [(k, a)]
toList LinComb v c
p ]

normalise :: DecidableZero c => LinComb x c -> LinComb x c
normalise :: forall c x. DecidableZero c => LinComb x c -> LinComb x c
normalise (LinComb Map x c
x) = Map x c -> LinComb x c
forall x c. Map x c -> LinComb x c
LinComb ((c -> Bool) -> Map x c -> Map x c
forall a k. (a -> Bool) -> Map k a -> Map k a
M.filter (Bool -> Bool
not (Bool -> Bool) -> (c -> Bool) -> c -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. c -> Bool
forall r. DecidableZero r => r -> Bool
isZero) Map x c
x)

instance (AbelianAdditive c,DecidableZero c,Ord e) => Additive (LinComb e c) where
  zero :: LinComb e c
zero = Map e c -> LinComb e c
forall x c. Map x c -> LinComb x c
LinComb Map e c
forall a. Additive a => a
zero
  LinComb Map e c
x + :: LinComb e c -> LinComb e c -> LinComb e c
+ LinComb Map e c
y = LinComb e c -> LinComb e c
forall c x. DecidableZero c => LinComb x c -> LinComb x c
normalise (Map e c -> LinComb e c
forall x c. Map x c -> LinComb x c
LinComb (Map e c
xMap e c -> Map e c -> Map e c
forall a. Additive a => a -> a -> a
+Map e c
y))

instance (AbelianAdditive c,Group c,DecidableZero c,Ord e) => Group (LinComb e c) where
  negate :: LinComb e c -> LinComb e c
negate = (c -> c) -> LinComb e c -> LinComb e c
forall a b. (a -> b) -> LinComb e a -> LinComb e b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap c -> c
forall a. Group a => a -> a
negate
  LinComb Map e c
x - :: LinComb e c -> LinComb e c -> LinComb e c
- LinComb Map e c
y = LinComb e c -> LinComb e c
forall c x. DecidableZero c => LinComb x c -> LinComb x c
normalise (Map e c -> LinComb e c
forall x c. Map x c -> LinComb x c
LinComb (Map e c
xMap e c -> Map e c -> Map e c
forall a. Group a => a -> a -> a
-Map e c
y))

-- Alternative instances for non-normalised version:
-- instance (Eq e, Eq c, Additive c) => Eq (LinComb e c) where
--    (==) = (==) `on` toList

-- instance (Ord e, Ord c, Additive c) => Ord (LinComb e c) where
--    compare = compare `on` toList

toList :: LinComb k a -> [(k, a)]
toList :: forall k a. LinComb k a -> [(k, a)]
toList = {- filter ((/= zero) . snd)  no need to filter zeros because normalised -} Map k a -> [(k, a)]
forall k a. Map k a -> [(k, a)]
M.assocs (Map k a -> [(k, a)])
-> (LinComb k a -> Map k a) -> LinComb k a -> [(k, a)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LinComb k a -> Map k a
forall x c. LinComb x c -> Map x c
fromLinComb 

var :: Multiplicative c => x -> LinComb x c
var :: forall c x. Multiplicative c => x -> LinComb x c
var x
x = Map x c -> LinComb x c
forall x c. Map x c -> LinComb x c
LinComb (x -> c -> Map x c
forall k a. k -> a -> Map k a
M.singleton x
x c
forall a. Multiplicative a => a
one)

-- | Convert from list without testing coefficients
unsafeFromList :: Ord v => [(v,c)] -> LinComb v c
unsafeFromList :: forall v c. Ord v => [(v, c)] -> LinComb v c
unsafeFromList = Map v c -> LinComb v c
forall x c. Map x c -> LinComb x c
LinComb (Map v c -> LinComb v c)
-> ([(v, c)] -> Map v c) -> [(v, c)] -> LinComb v c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(v, c)] -> Map v c
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList

fromList :: DecidableZero c => Additive c => Ord v => [(v,c)] -> LinComb v c
fromList :: forall c v.
(DecidableZero c, Additive c, Ord v) =>
[(v, c)] -> LinComb v c
fromList = LinComb v c -> LinComb v c
forall c x. DecidableZero c => LinComb x c -> LinComb x c
normalise (LinComb v c -> LinComb v c)
-> ([(v, c)] -> LinComb v c) -> [(v, c)] -> LinComb v c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map v c -> LinComb v c
forall x c. Map x c -> LinComb x c
LinComb (Map v c -> LinComb v c)
-> ([(v, c)] -> Map v c) -> [(v, c)] -> LinComb v c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (c -> c -> c) -> [(v, c)] -> Map v c
forall k a. Ord k => (a -> a -> a) -> [(k, a)] -> Map k a
M.fromListWith c -> c -> c
forall a. Additive a => a -> a -> a
(+)

instance (AbelianAdditive c, Eq c, DecidableZero c, Ord e) => DecidableZero (LinComb e c) where
  isZero :: LinComb e c -> Bool
isZero (LinComb Map e c
p) = Map e c
p Map e c -> Map e c -> Bool
forall a. Eq a => a -> a -> Bool
== Map e c
forall k a. Map k a
M.empty  

-- instance (Show c, Show e, Eq c, Multiplicative c) => Show (LinComb e c) where
--   show (LinComb xs) = intercalate "+" ([(if coef /= one then show coef else mempty) <> show m  | (m,coef) <- M.toList xs])

-- | Substitution by evaluation
subst :: DecidableZero c => AbelianAdditive c => Scalable c c => Ord v => (x -> LinComb v c) -> LinComb x c -> LinComb v c
subst :: forall c v x.
(DecidableZero c, AbelianAdditive c, Scalable c c, Ord v) =>
(x -> LinComb v c) -> LinComb x c -> LinComb v c
subst x -> LinComb v c
f = (c -> c) -> (x -> LinComb v c) -> LinComb x c -> LinComb v c
forall d x c v.
(Scalable d x, Additive x) =>
(c -> d) -> (v -> x) -> LinComb v c -> x
eval c -> c
forall a. a -> a
id x -> LinComb v c
f

-- | transform variables. coefficients are not touched
mapVars :: Ord x => (t -> x) -> LinComb t c -> LinComb x c
mapVars :: forall x t c. Ord x => (t -> x) -> LinComb t c -> LinComb x c
mapVars t -> x
f (LinComb Map t c
m) = [(x, c)] -> LinComb x c
forall v c. Ord v => [(v, c)] -> LinComb v c
unsafeFromList [(t -> x
f t
x, c
e) | (t
x,c
e) <- Map t c -> [(t, c)]
forall k a. Map k a -> [(k, a)]
M.assocs Map t c
m]

-- | Multiplies elements, assuming multiplication is monotonous.
mulVarsMonotonic :: Multiplicative x => x -> LinComb x c -> LinComb x c
mulVarsMonotonic :: forall x c. Multiplicative x => x -> LinComb x c -> LinComb x c
mulVarsMonotonic x
x (LinComb Map x c
m) = Map x c -> LinComb x c
forall x c. Map x c -> LinComb x c
LinComb ((x -> x) -> Map x c -> Map x c
forall k1 k2 a. (k1 -> k2) -> Map k1 a -> Map k2 a
M.mapKeysMonotonic (x
x x -> x -> x
forall a. Multiplicative a => a -> a -> a
*) Map x c
m) 

-- | transform variables with effect. coefficients are not touched
traverseVars :: Applicative f => Ord x => (v -> f x) -> LinComb v c -> f (LinComb x c)
traverseVars :: forall (f :: * -> *) x v c.
(Applicative f, Ord x) =>
(v -> f x) -> LinComb v c -> f (LinComb x c)
traverseVars v -> f x
f LinComb v c
e = [(x, c)] -> LinComb x c
forall v c. Ord v => [(v, c)] -> LinComb v c
unsafeFromList ([(x, c)] -> LinComb x c) -> f [(x, c)] -> f (LinComb x c)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((v, c) -> f (x, c)) -> [(v, c)] -> f [(x, c)]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse (\(v
x,c
c) -> (,c
c) (x -> (x, c)) -> f x -> f (x, c)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> v -> f x
f v
x) (LinComb v c -> [(v, c)]
forall k a. LinComb k a -> [(k, a)]
toList LinComb v c
e)

-- | transform variables and coefficients with effect.
bitraverse :: Applicative f => Ord x => (v -> f x) -> (c -> f d) -> LinComb v c -> f (LinComb x d)
bitraverse :: forall (f :: * -> *) x v c d.
(Applicative f, Ord x) =>
(v -> f x) -> (c -> f d) -> LinComb v c -> f (LinComb x d)
bitraverse v -> f x
f c -> f d
g LinComb v c
e = [(x, d)] -> LinComb x d
forall v c. Ord v => [(v, c)] -> LinComb v c
unsafeFromList ([(x, d)] -> LinComb x d) -> f [(x, d)] -> f (LinComb x d)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((v, c) -> f (x, d)) -> [(v, c)] -> f [(x, d)]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse (\(v
x,c
c) -> (,) (x -> d -> (x, d)) -> f x -> f (d -> (x, d))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> v -> f x
f v
x f (d -> (x, d)) -> f d -> f (x, d)
forall a b. f (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> c -> f d
g c
c) (LinComb v c -> [(v, c)]
forall k a. LinComb k a -> [(k, a)]
toList LinComb v c
e)