{-# LANGUAGE RebindableSyntax #-} -- | -- Module : Data.Array.Accelerate.Data.Functor -- Copyright : [2018..2020] The Accelerate Team -- License : BSD3 -- -- Maintainer : Trevor L. McDonell <trevor.mcdonell@gmail.com> -- Stability : experimental -- Portability : non-portable (GHC extensions) -- -- A functor performs a uniform action over a parameterised type -- -- This is essentially the same as the standard Haskell 'Prelude.Functor' class, -- lifted to Accelerate 'Exp' terms. -- -- @since 1.2.0.0 -- module Data.Array.Accelerate.Data.Functor ( Functor(..), (<$>), ($>), void, ) where import Data.Array.Accelerate.Sugar.Elt import Data.Array.Accelerate.Lift import Data.Array.Accelerate.Smart import Data.Monoid import Data.Semigroup import Prelude ( (.), const, flip ) -- | The 'Functor' class is used for scalar types which can be mapped over. -- Instances of 'Functor' should satisfy the following laws: -- -- > fmap id == id -- > fmap (f . g) == fmap f . fmap g -- class Functor f where fmap :: (Elt a, Elt b, Elt (f a), Elt (f b)) => (Exp a -> Exp b) -> Exp (f a) -> Exp (f b) -- | Replace all locations in the input with the same value. The default -- definition is @fmap . const@, but this may be overridden with a more -- efficient version. -- infixl 4 <$ (<$) :: (Elt a, Elt b, Elt (f a), Elt (f b)) => Exp a -> Exp (f b) -> Exp (f a) (<$) = fmap . const -- | An infix synonym for 'fmap' -- -- The name of this operator is an allusion to 'Prelude.$'. Note the -- similarities between their types: -- -- > ($) :: (Exp a -> Exp b) -> Exp a -> Exp b -- > (<$>) :: Functor f => (Exp a -> Exp b) -> Exp (f a) -> Exp (f b) -- -- Whereas 'Prelude.$' is function application, '<$>' is function application -- lifted over a 'Functor'. -- infixl 4 <$> (<$>) :: (Functor f, Elt a, Elt b, Elt (f a), Elt (f b)) => (Exp a -> Exp b) -> Exp (f a) -> Exp (f b) (<$>) = fmap -- | A flipped version of '(<$)'. -- infixl 4 $> ($>) :: (Functor f, Elt a, Elt b, Elt (f a), Elt (f b)) => Exp (f a) -> Exp b -> Exp (f b) ($>) = flip (<$) -- | @'void' value@ discards or ignores the result of evaluation. -- void :: (Functor f, Elt a, Elt (f a), Elt (f ())) => Exp (f a) -> Exp (f ()) void x = constant () <$ x instance Functor Sum where fmap f = lift1 (fmap f) instance Functor Product where fmap f = lift1 (fmap f) instance Functor Min where fmap f = lift1 (fmap f) instance Functor Max where fmap f = lift1 (fmap f)