{-# LANGUAGE LambdaCase #-}
{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}

module Data.List.ToolsYj (
	list, list', replicateWithI, replicateMWithI,
	elemAll, elemNotAll, findDefault, listToTuple4
	) where

import Data.Maybe
import Data.List ((\\), find)
import Data.List.NonEmpty (NonEmpty(..))

list :: b -> (a -> [a] -> b) -> [a] -> b
list :: forall b a. b -> (a -> [a] -> b) -> [a] -> b
list b
n a -> [a] -> b
c = \case [] -> b
n; a
x : [a]
xs -> a -> [a] -> b
c a
x [a]
xs

list' :: b -> (NonEmpty a -> b) -> [a] -> b
list' :: forall b a. b -> (NonEmpty a -> b) -> [a] -> b
list' b
n NonEmpty a -> b
c = \case [] -> b
n; a
x : [a]
xs -> NonEmpty a -> b
c (NonEmpty a -> b) -> NonEmpty a -> b
forall a b. (a -> b) -> a -> b
$ a
x a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [a]
xs

replicateWithI :: Int -> (Int -> a) -> [a]
replicateWithI :: forall a. Int -> (Int -> a) -> [a]
replicateWithI Int
n Int -> a
f = Int -> [a]
go Int
0
	where go :: Int -> [a]
go Int
i | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
n = Int -> a
f Int
i a -> [a] -> [a]
forall a. a -> [a] -> [a]
: Int -> [a]
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) | Bool
otherwise = []

replicateMWithI :: Applicative m => Int -> (Int -> m a) -> m [a]
replicateMWithI :: forall (m :: * -> *) a.
Applicative m =>
Int -> (Int -> m a) -> m [a]
replicateMWithI Int
n Int -> m a
f = Int -> m [a]
go Int
0
	where go :: Int -> m [a]
go Int
i | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
n = (:) (a -> [a] -> [a]) -> m a -> m ([a] -> [a])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> m a
f Int
i m ([a] -> [a]) -> m [a] -> m [a]
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> m [a]
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) | Bool
otherwise = [a] -> m [a]
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []

elemAll :: Eq a => [a] -> [a] -> Bool
elemAll :: forall a. Eq a => [a] -> [a] -> Bool
elemAll [a]
es = [a] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([a] -> Bool) -> ([a] -> [a]) -> [a] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([a]
es [a] -> [a] -> [a]
forall a. Eq a => [a] -> [a] -> [a]
\\)

elemNotAll :: Eq a => [a] -> [a] -> Bool
elemNotAll :: forall a. Eq a => [a] -> [a] -> Bool
elemNotAll [a]
es = Bool -> Bool
not (Bool -> Bool) -> ([a] -> Bool) -> [a] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> [a] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
elemAll [a]
es

findDefault :: a -> (a -> Bool) -> [a] -> a
findDefault :: forall a. a -> (a -> Bool) -> [a] -> a
findDefault a
d a -> Bool
p = a -> Maybe a -> a
forall a. a -> Maybe a -> a
fromMaybe a
d (Maybe a -> a) -> ([a] -> Maybe a) -> [a] -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Bool) -> [a] -> Maybe a
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find a -> Bool
p

listToTuple4 :: [a] -> (a, a, a, a)
listToTuple4 :: forall a. [a] -> (a, a, a, a)
listToTuple4 [a
r, a
g, a
b, a
a] = (a
r, a
g, a
b, a
a)
listToTuple4 [a]
_ = [Char] -> (a, a, a, a)
forall a. HasCallStack => [Char] -> a
error [Char]
"The length of the list is not 4"