{-# OPTIONS -Wno-orphans #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}

-- | This module contains all instances for V
--
module Data.V.Linear.Internal.Instances where

import Data.V.Linear.Internal.V
import Prelude.Linear.Internal
import qualified Unsafe.Linear as Unsafe
import qualified Data.Functor.Linear.Internal.Functor as Data
import qualified Data.Functor.Linear.Internal.Applicative as Data
import qualified Data.Functor.Linear.Internal.Traversable as Data
import GHC.TypeLits
import qualified Data.Vector as Vector


-- # Instances of V
-------------------------------------------------------------------------------

instance Data.Functor (V n) where
  fmap :: forall a b. (a %1 -> b) -> V n a %1 -> V n b
fmap a %1 -> b
f (V Vector a
xs) = Vector b %1 -> V n b
forall (n :: Nat) a. Vector a -> V n a
V (Vector b %1 -> V n b) %1 -> Vector b %1 -> V n b
forall a b. (a %1 -> b) %1 -> a %1 -> b
$ (Vector a -> Vector b) %1 -> Vector a %1 -> Vector b
forall a b. (a -> b) %1 -> a %1 -> b
Unsafe.toLinear ((a -> b) -> Vector a -> Vector b
forall a b. (a -> b) -> Vector a -> Vector b
Vector.map (\a
x -> a %1 -> b
f a
x)) Vector a
xs

instance KnownNat n => Data.Applicative (V n) where
  pure :: forall a. a -> V n a
pure a
a = Vector a %1 -> V n a
forall (n :: Nat) a. Vector a -> V n a
V (Vector a %1 -> V n a) %1 -> Vector a %1 -> V n a
forall a b. (a %1 -> b) %1 -> a %1 -> b
$ Int -> a -> Vector a
forall a. Int -> a -> Vector a
Vector.replicate (forall (n :: Nat). KnownNat n => Int
theLength @n) a
a
  (V Vector (a %1 -> b)
fs) <*> :: forall a b. V n (a %1 -> b) %1 -> V n a %1 -> V n b
<*> (V Vector a
xs) = Vector b %1 -> V n b
forall (n :: Nat) a. Vector a -> V n a
V (Vector b %1 -> V n b) %1 -> Vector b %1 -> V n b
forall a b. (a %1 -> b) %1 -> a %1 -> b
$
    (Vector (a %1 -> b) -> Vector a -> Vector b)
%1 -> Vector (a %1 -> b) %1 -> Vector a %1 -> Vector b
forall a b c. (a -> b -> c) %1 -> a %1 -> b %1 -> c
Unsafe.toLinear2 (((a %1 -> b) -> a -> b)
-> Vector (a %1 -> b) -> Vector a -> Vector b
forall a b c. (a -> b -> c) -> Vector a -> Vector b -> Vector c
Vector.zipWith (\a %1 -> b
f a
x -> a %1 -> b
f (a %1 -> b) %1 -> a %1 -> b
forall a b. (a %1 -> b) %1 -> a %1 -> b
$ a
x)) Vector (a %1 -> b)
fs Vector a
xs

instance KnownNat n => Data.Traversable (V n) where
  traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a %1 -> f b) -> V n a %1 -> f (V n b)
traverse a %1 -> f b
f (V Vector a
xs) =
    (Vector b %1 -> V n b
forall (n :: Nat) a. Vector a -> V n a
V (Vector b %1 -> V n b)
%1 -> ([b] %1 -> Vector b) %1 -> [b] %1 -> V n b
forall b c a. (b %1 -> c) %1 -> (a %1 -> b) %1 -> a %1 -> c
. ([b] -> Vector b) %1 -> [b] %1 -> Vector b
forall a b. (a -> b) %1 -> a %1 -> b
Unsafe.toLinear (Int -> [b] -> Vector b
forall a. Int -> [a] -> Vector a
Vector.fromListN (forall (n :: Nat). KnownNat n => Int
theLength @n))) ([b] %1 -> V n b) -> f [b] %1 -> f (V n b)
forall (f :: * -> *) a b. Functor f => (a %1 -> b) -> f a %1 -> f b
Data.<$>
    (a %1 -> f b) -> [a] %1 -> f [b]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a %1 -> f b) -> t a %1 -> f (t b)
Data.traverse a %1 -> f b
f ((Vector a -> [a]) %1 -> Vector a %1 -> [a]
forall a b. (a -> b) %1 -> a %1 -> b
Unsafe.toLinear Vector a -> [a]
forall a. Vector a -> [a]
Vector.toList Vector a
xs)