-- Copyright 2020 United States Government as represented by the Administrator
-- of the National Aeronautics and Space Administration. All Rights Reserved.
--
-- Disclaimers
--
-- Licensed under the Apache License, Version 2.0 (the "License"); you may
-- not use this file except in compliance with the License. You may obtain a
-- copy of the License at
--
--      https://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-- License for the specific language governing permissions and limitations
-- under the License.
--
-- | Auxiliary functions for working with values of type '[]'.
module Data.List.Extra where

-- External imports
import Data.List ( isSuffixOf )

-- | Safely extract the head of a list.
headEither :: [a] -> Either String a
headEither :: forall a. [a] -> Either String a
headEither (a
a:[a]
_) = a -> Either String a
forall a b. b -> Either a b
Right a
a
headEither []    = String -> Either String a
forall a b. a -> Either a b
Left String
"Empty list"

-- | Apply a transformation only to the head of a list.
toHead :: (a -> a) -> [a] -> [a]
toHead :: forall a. (a -> a) -> [a] -> [a]
toHead a -> a
f (a
x:[a]
xs) = a -> a
f a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
xs
toHead a -> a
_ [a]
xs     = [a]
xs

-- | Apply a transformation only to the tail of a list.
toTail :: (a -> a) -> [a] -> [a]
toTail :: forall a. (a -> a) -> [a] -> [a]
toTail a -> a
f (a
x:[a]
xs) = a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: (a -> a) -> [a] -> [a]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
f [a]
xs
toTail a -> a
_ [a]
xs     = [a]
xs

-- | Remove a suffix from a string, if present.
stripSuffix :: String -> String -> String
stripSuffix :: String -> String -> String
stripSuffix String
suffix String
string
  | String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
isSuffixOf String
suffix String
string = Int -> String -> String
forall a. Int -> [a] -> [a]
take (String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
string Int -> Int -> Int
forall a. Num a => a -> a -> a
- String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
suffix) String
string
  | Bool
otherwise                = String
string