-- |
-- Maintainer: Jeremy Nuttall <jeremy@jeremy-nuttall.com>
-- Stability : experimental
module Numeric.Noise.Internal (
  module Math,
  Noise (..),
  constant,
  remap,
  warp,
  reseed,
  blend,
  sliceX2,
  sliceY2,
  sliceX3,
  sliceY3,
  sliceZ3,
  Noise1',
  Noise1,
  mkNoise1,
  noise1At,
  Noise2',
  Noise2,
  mkNoise2,
  noise2At,
  next2,
  clamp2,
  const2,
  Noise3',
  Noise3,
  mkNoise3,
  noise3At,
  next3,
  clamp3,
  const3,
) where

import Numeric.Noise.Internal.Math as Math (
  Hash,
  Seed,
  clamp,
  cubicInterp,
  hermiteInterp,
  lerp,
  quinticInterp,
 )

-- |  'Noise' represents a function from a 'Seed' and coordinates @p@ to a noise
-- value @v@.
--
-- For convenience, dimension-specific type aliases are provided:
--
-- Use 'warp' to transform coordinates and 'remap' (or 'fmap') to transform values.
--
-- To evaluate noise functions, use 'noise1At', 'noise2At', or 'noise3At'
--
-- NB: 'Noise' is a lawful 'Profunctor' where 'lmap' = warp and 'rmap' = remap.
-- There are some useful implications to this, but pure-noise is committed to
-- a minimal dependency footprint and so will not provide this instance itself.
--
-- === __Algebraic composition__
--
-- 'Noise' can be composed algebraically:
--
-- @
-- combined :: Noise (Float, Float) Float
-- combined = (perlin2 + superSimplex2) / 2
-- @
--
-- === __Coordinate Transformation__
--
-- This allows you to, for example, compose multiple layers of noise at different
-- offsets.
--
-- @
-- scaled :: Noise2 Float
-- scaled = warp (\\(x, y) -> (x * 2, y * 2)) perlin2
-- @
newtype Noise p v = Noise {forall p v. Noise p v -> Seed -> p -> v
unNoise :: Seed -> p -> v}

-- NOTE: Noise p v is isomorphic to Reader (Seed, p), so it has trivial
-- instances of Monad and Category, Arrow, ArrowChoice, ArrowApply, etc.
--
-- I've decided not to include Category et al. as instances for now
-- because I can't come up with a use-case that is not sufficiently
-- covered by the monad instance.

-- | Noise admits 'Functor' on the value it produces
instance Functor (Noise p) where
  fmap :: forall a b. (a -> b) -> Noise p a -> Noise p b
fmap a -> b
f (Noise Seed -> p -> a
g) = (Seed -> p -> b) -> Noise p b
forall p v. (Seed -> p -> v) -> Noise p v
Noise (\Seed
seed -> a -> b
f (a -> b) -> (p -> a) -> p -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Seed -> p -> a
g Seed
seed)

-- | Noise admits 'Applicative' on the value it produces
instance Applicative (Noise p) where
  pure :: forall a. a -> Noise p a
pure a
a = (Seed -> p -> a) -> Noise p a
forall p v. (Seed -> p -> v) -> Noise p v
Noise ((Seed -> p -> a) -> Noise p a) -> (Seed -> p -> a) -> Noise p a
forall a b. (a -> b) -> a -> b
$ \Seed
_ p
_ -> a
a
  liftA2 :: forall a b c. (a -> b -> c) -> Noise p a -> Noise p b -> Noise p c
liftA2 a -> b -> c
f (Noise Seed -> p -> a
g) (Noise Seed -> p -> b
h) = (Seed -> p -> c) -> Noise p c
forall p v. (Seed -> p -> v) -> Noise p v
Noise (\Seed
s p
p -> Seed -> p -> a
g Seed
s p
p a -> b -> c
`f` Seed -> p -> b
h Seed
s p
p)

-- | Note: The 'Monad' instance evaluates all noise functions at the same
-- seed and coordinate. For independent sampling at different coordinates,
-- use 'warp' to transform the coordinate space.
--
-- @
-- do n1 <- perlin2
--    n2 <- superSimplex2
--    return (n1 + n2)
-- @
--
-- is equivalent to:
--
-- @
-- perlin2 + superSimplex2
-- @
--
-- This is useful for domain warping.
instance Monad (Noise p) where
  Noise Seed -> p -> a
g >>= :: forall a b. Noise p a -> (a -> Noise p b) -> Noise p b
>>= a -> Noise p b
f = (Seed -> p -> b) -> Noise p b
forall p v. (Seed -> p -> v) -> Noise p v
Noise (\Seed
s p
p -> Noise p b -> Seed -> p -> b
forall p v. Noise p v -> Seed -> p -> v
unNoise (a -> Noise p b
f (Seed -> p -> a
g Seed
s p
p)) Seed
s p
p)

instance (Num a) => Num (Noise p a) where
  + :: Noise p a -> Noise p a -> Noise p a
(+) = (a -> a -> a) -> Noise p a -> Noise p a -> Noise p a
forall a b c. (a -> b -> c) -> Noise p a -> Noise p b -> Noise p c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> a
forall a. Num a => a -> a -> a
(+)
  * :: Noise p a -> Noise p a -> Noise p a
(*) = (a -> a -> a) -> Noise p a -> Noise p a -> Noise p a
forall a b c. (a -> b -> c) -> Noise p a -> Noise p b -> Noise p c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> a
forall a. Num a => a -> a -> a
(*)
  abs :: Noise p a -> Noise p a
abs = (a -> a) -> Noise p a -> Noise p a
forall a b. (a -> b) -> Noise p a -> Noise p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Num a => a -> a
abs
  signum :: Noise p a -> Noise p a
signum = (a -> a) -> Noise p a -> Noise p a
forall a b. (a -> b) -> Noise p a -> Noise p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Num a => a -> a
signum
  fromInteger :: Integer -> Noise p a
fromInteger Integer
i = a -> Noise p a
forall a. a -> Noise p a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Integer -> a
forall a. Num a => Integer -> a
fromInteger Integer
i)
  negate :: Noise p a -> Noise p a
negate = (a -> a) -> Noise p a -> Noise p a
forall a b. (a -> b) -> Noise p a -> Noise p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Num a => a -> a
negate

instance (Fractional a) => Fractional (Noise p a) where
  fromRational :: Rational -> Noise p a
fromRational = a -> Noise p a
forall a. a -> Noise p a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a -> Noise p a) -> (Rational -> a) -> Rational -> Noise p a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> a
forall a. Fractional a => Rational -> a
fromRational
  recip :: Noise p a -> Noise p a
recip = (a -> a) -> Noise p a -> Noise p a
forall a b. (a -> b) -> Noise p a -> Noise p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Fractional a => a -> a
recip
  / :: Noise p a -> Noise p a -> Noise p a
(/) = (a -> a -> a) -> Noise p a -> Noise p a -> Noise p a
forall a b c. (a -> b -> c) -> Noise p a -> Noise p b -> Noise p c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> a
forall a. Fractional a => a -> a -> a
(/)

instance (Floating a) => Floating (Noise p a) where
  pi :: Noise p a
pi = a -> Noise p a
forall a. a -> Noise p a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
forall a. Floating a => a
pi
  exp :: Noise p a -> Noise p a
exp = (a -> a) -> Noise p a -> Noise p a
forall a b. (a -> b) -> Noise p a -> Noise p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
exp
  log :: Noise p a -> Noise p a
log = (a -> a) -> Noise p a -> Noise p a
forall a b. (a -> b) -> Noise p a -> Noise p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
log
  sin :: Noise p a -> Noise p a
sin = (a -> a) -> Noise p a -> Noise p a
forall a b. (a -> b) -> Noise p a -> Noise p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
sin
  cos :: Noise p a -> Noise p a
cos = (a -> a) -> Noise p a -> Noise p a
forall a b. (a -> b) -> Noise p a -> Noise p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
cos
  asin :: Noise p a -> Noise p a
asin = (a -> a) -> Noise p a -> Noise p a
forall a b. (a -> b) -> Noise p a -> Noise p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
asin
  acos :: Noise p a -> Noise p a
acos = (a -> a) -> Noise p a -> Noise p a
forall a b. (a -> b) -> Noise p a -> Noise p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
acos
  atan :: Noise p a -> Noise p a
atan = (a -> a) -> Noise p a -> Noise p a
forall a b. (a -> b) -> Noise p a -> Noise p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
atan
  sinh :: Noise p a -> Noise p a
sinh = (a -> a) -> Noise p a -> Noise p a
forall a b. (a -> b) -> Noise p a -> Noise p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
sinh
  cosh :: Noise p a -> Noise p a
cosh = (a -> a) -> Noise p a -> Noise p a
forall a b. (a -> b) -> Noise p a -> Noise p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
cosh
  asinh :: Noise p a -> Noise p a
asinh = (a -> a) -> Noise p a -> Noise p a
forall a b. (a -> b) -> Noise p a -> Noise p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
asinh
  acosh :: Noise p a -> Noise p a
acosh = (a -> a) -> Noise p a -> Noise p a
forall a b. (a -> b) -> Noise p a -> Noise p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
acosh
  atanh :: Noise p a -> Noise p a
atanh = (a -> a) -> Noise p a -> Noise p a
forall a b. (a -> b) -> Noise p a -> Noise p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
atanh

type Noise1' p v = Noise p v
type Noise1 v = Noise1' v v

mkNoise1 :: (Seed -> p -> v) -> Noise1' p v
mkNoise1 :: forall p v. (Seed -> p -> v) -> Noise p v
mkNoise1 = (Seed -> p -> v) -> Noise p v
forall p v. (Seed -> p -> v) -> Noise p v
Noise
{-# INLINE mkNoise1 #-}

-- | Evaluate a 1D noise function at the given coordinates with the given seed.
-- Currently, you must use a slicing function like 'sliceX' to reduce
-- higher-dimensional noise into 1D noise.
noise1At :: Noise1 a -> Seed -> a -> a
noise1At :: forall a. Noise1 a -> Seed -> a -> a
noise1At = Noise a a -> Seed -> a -> a
forall p v. Noise p v -> Seed -> p -> v
unNoise
{-# INLINE noise1At #-}

type Noise2' p v = Noise (p, p) v
type Noise2 v = Noise2' v v

mkNoise2 :: (Seed -> p -> p -> v) -> Noise2' p v
mkNoise2 :: forall p v. (Seed -> p -> p -> v) -> Noise2' p v
mkNoise2 Seed -> p -> p -> v
f = (Seed -> (p, p) -> v) -> Noise (p, p) v
forall p v. (Seed -> p -> v) -> Noise p v
Noise (\Seed
s (p
x, p
y) -> Seed -> p -> p -> v
f Seed
s p
x p
y)
{-# INLINE mkNoise2 #-}

-- | Evaluate a 2D noise function at the given coordinates with the given seed.
noise2At
  :: Noise2 a
  -> Seed
  -- ^ deterministic seed
  -> a
  -- ^ x coordinate
  -> a
  -- ^ y coordinate
  -> a
noise2At :: forall a. Noise2 a -> Seed -> a -> a -> a
noise2At (Noise Seed -> (a, a) -> a
f) Seed
seed a
x a
y = Seed -> (a, a) -> a
f Seed
seed (a
x, a
y)
{-# INLINE noise2At #-}

type Noise3' p v = Noise (p, p, p) v
type Noise3 v = Noise3' v v

mkNoise3 :: (Seed -> p -> p -> p -> v) -> Noise3' p v
mkNoise3 :: forall p v. (Seed -> p -> p -> p -> v) -> Noise3' p v
mkNoise3 Seed -> p -> p -> p -> v
f = (Seed -> (p, p, p) -> v) -> Noise (p, p, p) v
forall p v. (Seed -> p -> v) -> Noise p v
Noise (\Seed
s (p
x, p
y, p
z) -> Seed -> p -> p -> p -> v
f Seed
s p
x p
y p
z)
{-# INLINE mkNoise3 #-}

-- | Evaluate a 3D noise function at the given coordinates with the given seed.
noise3At
  :: Noise3 a
  -> Seed
  -- ^ deterministic seed
  -> a
  -- ^ x coordinate
  -> a
  -- ^ y coordinate
  -> a
  -- ^ z coordinate
  -> a
noise3At :: forall a. Noise3 a -> Seed -> a -> a -> a -> a
noise3At (Noise Seed -> (a, a, a) -> a
f) Seed
seed a
x a
y a
z = Seed -> (a, a, a) -> a
f Seed
seed (a
x, a
y, a
z)
{-# INLINE noise3At #-}

-- | Transform the values produced by a noise function.
--
-- This is an alias for 'fmap'. Use it to transform noise values after generation:
--
-- === __Examples__
--
-- @
-- -- Scale noise from [-1, 1] to [0, 1]
-- normalized :: Noise2 Float
-- normalized = remap (\\x -> (x + 1) / 2) perlin2
-- @
remap :: (a -> b) -> Noise p a -> Noise p b
remap :: forall a b p. (a -> b) -> Noise p a -> Noise p b
remap = (a -> b) -> Noise p a -> Noise p b
forall a b. (a -> b) -> Noise p a -> Noise p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
{-# INLINE remap #-}

-- | Transform the coordinate space of a noise function.
--
-- This allows you to scale, rotate, or otherwise modify coordinates before
-- they're passed to the noise function:
--
-- NB: This is 'contramap'
--
-- === __Examples__
--
-- @
-- -- Scale the noise frequency
-- scaled :: Noise2 Float
-- scaled = warp (\\(x, y) -> (x * 2, y * 2)) perlin2
--
-- -- Rotate the noise field
-- rotated :: Noise2 Float
-- rotated = warp (\\(x, y) -> (x * cos a - y * sin a, x * sin a + y * cos a)) perlin2
--   where a = pi / 4
-- @
warp :: (p -> p') -> Noise p' v -> Noise p v
warp :: forall p p' v. (p -> p') -> Noise p' v -> Noise p v
warp p -> p'
f (Noise Seed -> p' -> v
g) = (Seed -> p -> v) -> Noise p v
forall p v. (Seed -> p -> v) -> Noise p v
Noise (\Seed
s p
p -> Seed -> p' -> v
g Seed
s (p -> p'
f p
p))
{-# INLINE warp #-}

-- | Modify the seed used by a noise function.
--
-- This is useful for generating independent layers of noise:
--
-- See also 'next2' and 'next3' for convenient increment-by-one variants.
--
-- === __Examples__
-- @
-- layer1 = perlin2
-- layer2 = reseed (+1) perlin2
-- layer3 = reseed (+2) perlin2
--
-- combined = (layer1 + layer2 + layer3) / 3
-- @
reseed :: (Seed -> Seed) -> Noise p a -> Noise p a
reseed :: forall p a. (Seed -> Seed) -> Noise p a -> Noise p a
reseed Seed -> Seed
f (Noise Seed -> p -> a
g) = (Seed -> p -> a) -> Noise p a
forall p v. (Seed -> p -> v) -> Noise p v
Noise (Seed -> p -> a
g (Seed -> p -> a) -> (Seed -> Seed) -> Seed -> p -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Seed -> Seed
f)
{-# INLINE reseed #-}

constant :: a -> Noise c a
constant :: forall a c. a -> Noise c a
constant = a -> Noise c a
forall a. a -> Noise c a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
{-# INLINE constant #-}

-- | Combine two noise functions with a custom blending function.
--
-- This is an alias for 'liftA2'. Use it to mix multiple noise sources:
--
-- @
-- -- Multiply two noise functions
-- multiplied :: Noise2 Float
-- multiplied = blend (*) perlin2 superSimplex2
--
-- -- Custom blending based on values
-- custom :: Noise2 Float
-- custom = blend (\\a b -> if a > 0 then a else b) perlin2 superSimplex2
-- @
blend :: (a -> b -> c) -> Noise p a -> Noise p b -> Noise p c
blend :: forall a b c p.
(a -> b -> c) -> Noise p a -> Noise p b -> Noise p c
blend = (a -> b -> c) -> Noise p a -> Noise p b -> Noise p c
forall a b c. (a -> b -> c) -> Noise p a -> Noise p b -> Noise p c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2
{-# INLINE blend #-}

-- | Clamp a noise function between the given lower and higher bound
clampNoise :: (Ord a) => a -> a -> Noise p a -> Noise p a
clampNoise :: forall a p. Ord a => a -> a -> Noise p a -> Noise p a
clampNoise a
l a
u = (a -> a) -> Noise p a -> Noise p a
forall a b. (a -> b) -> Noise p a -> Noise p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a -> a -> a -> a
forall a. Ord a => a -> a -> a -> a
clamp a
l a
u)
{-# INLINE clampNoise #-}

-- | Slice a 2D noise function at a fixed X coordinate to produce 1D noise.
--
-- === __Examples__
--
-- @
-- noise1d :: Noise1 Float
-- noise1d = sliceX2 0.0 perlin2  -- Fix X at 0, vary Y
--
-- -- Evaluate at Y = 5.0
-- value = noise1At noise1d seed 5.0
-- @
sliceX2 :: p -> Noise2' p v -> Noise1' p v
sliceX2 :: forall p v. p -> Noise2' p v -> Noise1' p v
sliceX2 p
x = (p -> (p, p)) -> Noise (p, p) v -> Noise p v
forall p p' v. (p -> p') -> Noise p' v -> Noise p v
warp (p
x,)
{-# INLINE sliceX2 #-}

-- | Slice a 2D noise function at a fixed Y coordinate to produce 1D noise.
--
-- === __Examples__
--
-- @
-- noise1d :: Noise1 Float
-- noise1d = sliceY2 0.0 perlin2  -- Fix Y at 0, vary X
--
-- -- Evaluate at X = 5.0
-- value = noise1At noise1d seed 5.0
-- @
sliceY2 :: p -> Noise2' p v -> Noise1' p v
sliceY2 :: forall p v. p -> Noise2' p v -> Noise1' p v
sliceY2 p
y = (p -> (p, p)) -> Noise (p, p) v -> Noise p v
forall p p' v. (p -> p') -> Noise p' v -> Noise p v
warp (,p
y)
{-# INLINE sliceY2 #-}

-- | Slice a 3D noise function at a fixed X coordinate to produce 2D noise.
--
-- === __Examples__
--
-- @
-- noise2d :: Noise2 Float
-- noise2d = sliceX3 0.0 perlin3  -- Fix X at 0, vary Y and Z
--
-- -- Evaluate at Y = 1.0, Z = 2.0
-- value = noise2At noise2d seed 1.0 2.0
-- @
sliceX3 :: p -> Noise3' p v -> Noise2' p v
sliceX3 :: forall p v. p -> Noise3' p v -> Noise2' p v
sliceX3 p
x = ((p, p) -> (p, p, p)) -> Noise (p, p, p) v -> Noise (p, p) v
forall p p' v. (p -> p') -> Noise p' v -> Noise p v
warp (\(p
y, p
z) -> (p
x, p
y, p
z))
{-# INLINE sliceX3 #-}

-- | Slice a 3D noise function at a fixed Y coordinate to produce 2D noise.
--
-- === __Examples__
--
-- @
-- noise2d :: Noise2 Float
-- noise2d = sliceY3 0.0 perlin3  -- Fix Y at 0, vary X and Z
-- @
sliceY3 :: p -> Noise3' p v -> Noise2' p v
sliceY3 :: forall p v. p -> Noise3' p v -> Noise2' p v
sliceY3 p
y = ((p, p) -> (p, p, p)) -> Noise (p, p, p) v -> Noise (p, p) v
forall p p' v. (p -> p') -> Noise p' v -> Noise p v
warp (\(p
x, p
z) -> (p
x, p
y, p
z))
{-# INLINE sliceY3 #-}

-- | Slice a 3D noise function at a fixed Z coordinate to produce 2D noise.
--
-- This is useful for extracting 2D slices from 3D noise at different heights:
--
-- === __Examples__
--
-- @
-- heightmap :: Noise2 Float
-- heightmap = sliceZ3 10.0 perlin3  -- Sample at Z = 10
-- @
sliceZ3 :: p -> Noise3' p v -> Noise2' p v
sliceZ3 :: forall p v. p -> Noise3' p v -> Noise2' p v
sliceZ3 p
z = ((p, p) -> (p, p, p)) -> Noise (p, p, p) v -> Noise (p, p) v
forall p p' v. (p -> p') -> Noise p' v -> Noise p v
warp (\(p
x, p
y) -> (p
x, p
y, p
z))
{-# INLINE sliceZ3 #-}

-- | Increment the seed for a 2D noise function. See 'reseed'
next2 :: Noise2 a -> Noise2 a
next2 :: forall a. Noise2 a -> Noise2 a
next2 = (Seed -> Seed) -> Noise (a, a) a -> Noise (a, a) a
forall p a. (Seed -> Seed) -> Noise p a -> Noise p a
reseed (Seed -> Seed -> Seed
forall a. Num a => a -> a -> a
+ Seed
1)
{-# INLINE next2 #-}

-- | Clamp the output of a 2D noise function to the range @[lower, upper]@.
clamp2 :: (Ord a) => a -> a -> Noise2 a -> Noise2 a
clamp2 :: forall a. Ord a => a -> a -> Noise2 a -> Noise2 a
clamp2 = a -> a -> Noise (a, a) a -> Noise (a, a) a
forall a p. Ord a => a -> a -> Noise p a -> Noise p a
clampNoise
{-# INLINE clamp2 #-}

-- | A noise function that produces the same value everywhere. Alias of 'pure'.
const2 :: a -> Noise2 a
const2 :: forall a. a -> Noise2 a
const2 = a -> Noise (a, a) a
forall a. a -> Noise (a, a) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
{-# INLINE const2 #-}

-- | Increment the seed for a 3D noise function. See 'reseed'
next3 :: Noise3 a -> Noise3 a
next3 :: forall a. Noise3 a -> Noise3 a
next3 = (Seed -> Seed) -> Noise (a, a, a) a -> Noise (a, a, a) a
forall p a. (Seed -> Seed) -> Noise p a -> Noise p a
reseed (Seed -> Seed -> Seed
forall a. Num a => a -> a -> a
+ Seed
1)
{-# INLINE next3 #-}

-- | A noise function that produces the same value everywhere. Alias of 'pure'
--
-- Used to provide the 'Num' instance.
const3 :: a -> Noise3 a
const3 :: forall a. a -> Noise3 a
const3 = a -> Noise (a, a, a) a
forall a. a -> Noise (a, a, a) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
{-# INLINE const3 #-}

-- | Clamp the output of a 3D noise function to the range @[lower, upper]@.
clamp3 :: (Ord a) => a -> a -> Noise3 a -> Noise3 a
clamp3 :: forall a. Ord a => a -> a -> Noise3 a -> Noise3 a
clamp3 = a -> a -> Noise (a, a, a) a -> Noise (a, a, a) a
forall a p. Ord a => a -> a -> Noise p a -> Noise p a
clampNoise
{-# INLINE clamp3 #-}