{-# LANGUAGE Trustworthy #-}

{- |
Copyright:  (c) 2016 Stephen Diehl
            (c) 2016-2018 Serokell
            (c) 2018-2019 Kowainik
SPDX-License-Identifier: MIT
Maintainer: Kowainik <xrom.xkov@gmail.com>

Utility functions to work with lists.
-}

module Relude.List
       ( module Relude.List.NonEmpty
       , module Relude.List.Reexport
       , (!!?)
       ) where


import Relude.Base ((<))
import Relude.Bool (otherwise)
import Relude.List.NonEmpty
import Relude.List.Reexport
import Relude.Monad (Maybe (..))
import Relude.Numeric (Int, (-))


-- $setup
-- >>> import Relude

{- | Safer version of 'Relude.Unsafe.!!', returns a Maybe.
get element from list using index value starting from `0`.

>>> [] !!? 0
Nothing

>>> ["a", "b", "c"] !!? 3
Nothing

>>> [1, 2, 3] !!? (-1)
Nothing

>>> ["a", "b", "c"] !!? 2
Just "c"

@since 0.6.0.0
-}
infix 9 !!?
(!!?) :: [a] -> Int -> Maybe a
!!? :: [a] -> Int -> Maybe a
(!!?) xs :: [a]
xs i :: Int
i
    | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 0     = Maybe a
forall a. Maybe a
Nothing
    | Bool
otherwise = Int -> [a] -> Maybe a
forall a. Int -> [a] -> Maybe a
go Int
i [a]
xs
  where
    go :: Int -> [a] -> Maybe a
    go :: Int -> [a] -> Maybe a
go 0 (x :: a
x:_)  = a -> Maybe a
forall a. a -> Maybe a
Just a
x
    go j :: Int
j (_:ys :: [a]
ys) = Int -> [a] -> Maybe a
forall a. Int -> [a] -> Maybe a
go (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1) [a]
ys
    go _ []     = Maybe a
forall a. Maybe a
Nothing
{-# INLINE (!!?) #-}