```--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--Module       : Misc
--Author       : Joe Fredette
--
--Maintainer   : Joe Fredette <jfredett.at.gmail.dot.com>
--Stability    : Unstable
--Portability  : portable
--
--------------------------------------------------------------------------------
--Description  : Misc. helper functions.
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
{-# LANGUAGE FlexibleInstances #-}
module HackMail.Control.Misc where

import Control.Arrow
import Data.Char

if' p t f = if p then t else f

instance Show (a -> b) where
show _ = "FUNCTION"

pairToList :: ([a],[a]) -> [a]
pairToList (a,b) = a++b

both :: Arrow a => a b c -> a (b, b) (c, c)
both a = a *** a

double :: Arrow a => a b c -> a b (c,c)
double a = a &&& a

(^|^) f g (x,y) = first (f x) >>> second (g y)
dupe f = f ^|^ f

(^&^) f g p i = (f ^|^ g) p \$ (i, i)
copy f = f ^&^ f

appBoth :: (a -> b, c -> d) -> a -> c -> (b, d)
appBoth (f,g) x y = (f x, g y)

appDouble :: (a -> b, a -> b) -> a -> (b,b)
appDouble (f,g) x = (f x, g x)

--- (map foo *** map bar) quux -> (dupe map) (foo, bar) quux
--
-- a1 (a2 b c) (a2 (f a) (f b))

--- Maybe stuff...

maybeToBool :: Maybe a -> Bool
maybeToBool Nothing = False
maybeToBool _       = True

-- These are pulled out of my ass, are they useful at all?
maybeAnd, maybeOr :: Maybe a -> Maybe a -> Maybe (a,a)
maybeIf :: Maybe a -> Maybe a -> Maybe a -> Maybe a

maybeAnd Nothing _ = Nothing
maybeAnd _ Nothing = Nothing
maybeAnd (Just a) (Just b) = Just (a,b)

maybeOr Nothing Nothing   = Nothing
maybeOr Nothing (Just b)  = Just (b,b)
maybeOr (Just a) Nothing  = Just (a,a)
maybeOr (Just a) (Just b) = Just (a,b)

maybeIf Nothing Nothing   _  = Nothing
maybeIf Nothing (Just a)  _  = Just a
maybeIf (Just a) _ Nothing   = Nothing
maybeIf (Just a) _ (Just b)  = Just b
```