-- |
-- Module      : Conjure.Utils
-- Copyright   : (c) 2021 Rudy Matela
-- License     : 3-Clause BSD  (see the file LICENSE)
-- Maintainer  : Rudy Matela <rudy@matela.com.br>
--
-- An internal module of 'Conjure'.
-- This exports 'Data.List', 'Data.Maybe', 'Data.Function'
-- and a few other simple utitilites.
{-# LANGUAGE CPP #-}
module Conjure.Utils
  ( module Data.List
  , module Data.Function
  , module Data.Maybe
  , module Data.Monoid
  , module Data.Tuple
  , module Data.Typeable

  , count
  , nubOn
  , iterateUntil
  , mzip
  )
where

import Data.List
import Data.Function
import Data.Maybe
import Data.Monoid
import Data.Tuple
import Data.Typeable

count :: (a -> Bool) -> [a] -> Int
count :: (a -> Bool) -> [a] -> Int
count a -> Bool
p  =  [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([a] -> Int) -> ([a] -> [a]) -> [a] -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Bool) -> [a] -> [a]
forall a. (a -> Bool) -> [a] -> [a]
filter a -> Bool
p

nubOn :: Eq b => (a -> b) -> [a] -> [a]
nubOn :: (a -> b) -> [a] -> [a]
nubOn a -> b
f  =  (a -> a -> Bool) -> [a] -> [a]
forall a. (a -> a -> Bool) -> [a] -> [a]
nubBy (b -> b -> Bool
forall a. Eq a => a -> a -> Bool
(==) (b -> b -> Bool) -> (a -> b) -> a -> a -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` a -> b
f)

iterateUntil :: (a -> a -> Bool) -> (a -> a) -> a -> a
iterateUntil :: (a -> a -> Bool) -> (a -> a) -> a -> a
iterateUntil a -> a -> Bool
(?) a -> a
f  =  a -> a
iu
  where
  iu :: a -> a
iu a
x | a
x a -> a -> Bool
? a
fx     =  a
x
       | Bool
otherwise  =  a -> a
iu a
fx
    where
    fx :: a
fx  =  a -> a
f a
x

mzip :: Monoid a => [a] -> [a] -> [a]
mzip :: [a] -> [a] -> [a]
mzip [] []  =  []
mzip [] [a]
ys  =  [a]
ys
mzip [a]
xs []  =  [a]
xs
mzip (a
x:[a]
xs) (a
y:[a]
ys)  =  a
x a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
y a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a] -> [a] -> [a]
forall a. Monoid a => [a] -> [a] -> [a]
mzip [a]
xs [a]
ys