{-# LANGUAGE ExplicitForAll #-}

-- | Extra functions relating to functions (higher-order functions)
module Hextra.Function where

import Hextra.Maybe

curry3 :: forall a b c d. ((a, b, c) -> d) -> a -> b -> c -> d
curry3 :: ((a, b, c) -> d) -> a -> b -> c -> d
curry3 (a, b, c) -> d
f a
x b
y c
z = (a, b, c) -> d
f (a
x, b
y, c
z)
-- ^ Like curry, but for functions with three arguments

uncurry3 :: forall a b c d. (a -> b -> c -> d) -> (a, b, c) -> d
uncurry3 :: (a -> b -> c -> d) -> (a, b, c) -> d
uncurry3 a -> b -> c -> d
f (a
x, b
y, c
z) = a -> b -> c -> d
f a
x b
y c
z
-- ^ Like uncurry, but for functions with three arguments

uncurry3' :: forall a b c d. (a -> b -> c -> d) -> a -> (b, c) -> d
uncurry3' :: (a -> b -> c -> d) -> a -> (b, c) -> d
uncurry3' a -> b -> c -> d
f a
a (b
b, c
c) = a -> b -> c -> d
f a
a b
b c
c

curry4 :: forall a b c d e. ((a, b, c, d) -> e) -> a -> b -> c -> d -> e
curry4 :: ((a, b, c, d) -> e) -> a -> b -> c -> d -> e
curry4 (a, b, c, d) -> e
f a
x b
y c
z d
w = (a, b, c, d) -> e
f (a
x, b
y, c
z, d
w)
-- ^ Like curry, but for functions with four arguments

uncurry4 :: forall a b c d e. (a -> b -> c -> d -> e) -> (a, b, c, d) -> e
uncurry4 :: (a -> b -> c -> d -> e) -> (a, b, c, d) -> e
uncurry4 a -> b -> c -> d -> e
f (a
x, b
y, c
z, d
w) = a -> b -> c -> d -> e
f a
x b
y c
z d
w
-- ^ Like uncurry, but for functions with four arguments

applyIfJustMonoid :: forall a b x. Monoid x => (a -> b) -> (x -> a) -> Maybe x -> b
applyIfJustMonoid :: (a -> b) -> (x -> a) -> Maybe x -> b
applyIfJustMonoid a -> b
g x -> a
f Maybe x
m = a -> b
g (a -> b) -> (x -> a) -> x -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. x -> a
f (x -> b) -> x -> b
forall a b. (a -> b) -> a -> b
$ x -> Maybe x -> x
forall a. a -> Maybe a -> a
fromNothing x
forall a. Monoid a => a
mempty Maybe x
m

combineIfJust' :: forall a b x. (a -> b -> b) -> (x -> a) -> Maybe x -> b -> b
combineIfJust' :: (a -> b -> b) -> (x -> a) -> Maybe x -> b -> b
combineIfJust' a -> b -> b
g x -> a
f Maybe x
m b
b = (b -> b) -> Maybe (b -> b) -> b -> b
forall a. a -> Maybe a -> a
fromNothing b -> b
forall a. a -> a
id ((a -> b -> b
g (a -> b -> b) -> (x -> a) -> x -> b -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. x -> a
f) (x -> b -> b) -> Maybe x -> Maybe (b -> b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe x
m) b
b
-- ^ Combines two things where one of them is wrapped in Maybe
-- If the Maybe thing is Nothing, just return the plain thing
-- Requires that 2nd argument type and output type of the combining function are the same

infixr 9 <.
(<.) :: forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
<. :: (b -> b -> c) -> (a -> b) -> a -> a -> c
(<.) b -> b -> c
f a -> b
g a
x a
y = b -> b -> c
f (a -> b
g a
x) (a -> b
g a
y)
-- ^ Applies a unary function on the inputs of a binary function

infixr 9 .>
(.>) :: forall b c a. (b -> c) -> (a -> a -> b) -> a -> a -> c
.> :: (b -> c) -> (a -> a -> b) -> a -> a -> c
(.>) b -> c
f a -> a -> b
g a
x a
y = b -> c
f (a -> a -> b
g a
x a
y)
-- ^ Applies a unary function on the output of a binary function

infixr 9 .<
(.<) :: forall a b c. (a -> a -> b) -> (b -> c) -> a -> a -> c
.< :: (a -> a -> b) -> (b -> c) -> a -> a -> c
(.<) = ((b -> c) -> (a -> a -> b) -> a -> a -> c)
-> (a -> a -> b) -> (b -> c) -> a -> a -> c
forall a b c. (a -> b -> c) -> b -> a -> c
flip (b -> c) -> (a -> a -> b) -> a -> a -> c
forall b c a. (b -> c) -> (a -> a -> b) -> a -> a -> c
(.>)
-- ^ Flipped (.\>)

infixr 9 >.
(>.) :: forall a b c. (a -> b) -> (b -> b -> c) -> a -> a -> c
>. :: (a -> b) -> (b -> b -> c) -> a -> a -> c
(>.) = ((b -> b -> c) -> (a -> b) -> a -> a -> c)
-> (a -> b) -> (b -> b -> c) -> a -> a -> c
forall a b c. (a -> b -> c) -> b -> a -> c
flip (b -> b -> c) -> (a -> b) -> a -> a -> c
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
(<.)
-- ^ Flipped (\<.)

infixr 9 <.-
(<.-) :: forall a b c. (a -> b) -> (b -> c) -> a -> c
<.- :: (a -> b) -> (b -> c) -> a -> c
(<.-) = ((b -> c) -> (a -> b) -> a -> c) -> (a -> b) -> (b -> c) -> a -> c
forall a b c. (a -> b -> c) -> b -> a -> c
flip (b -> c) -> (a -> b) -> a -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
(.)
-- ^ Flipped (.)