{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies          #-}

module HaskellWorks.Data.Uncons
    ( Container(..)
    , Uncons(..)
    ) where

import Data.Int
import Data.Maybe
import Data.Word
import HaskellWorks.Data.Container
import HaskellWorks.Data.Drop
import Prelude                     hiding (drop)

import qualified Data.ByteString      as BS
import qualified Data.Vector          as DV
import qualified Data.Vector.Storable as DVS

class Drop v => Uncons v where
  uncons :: v -> Maybe (Elem v, v)

instance Uncons String where
  uncons :: String -> Maybe (Elem String, String)
uncons String
s = case String
s of
    (Char
x:String
xs) -> forall a. a -> Maybe a
Just (Char
x, String
xs)
    String
_      -> forall a. Maybe a
Nothing
  {-# INLINE uncons   #-}

instance Uncons BS.ByteString where
  uncons :: ByteString -> Maybe (Elem ByteString, ByteString)
uncons = ByteString -> Maybe (Word8, ByteString)
BS.uncons
  {-# INLINE uncons   #-}

instance Uncons (DV.Vector Word8) where
  uncons :: Vector Word8 -> Maybe (Elem (Vector Word8), Vector Word8)
uncons Vector Word8
s = if forall a. Vector a -> Int
DV.length Vector Word8
s forall a. Eq a => a -> a -> Bool
== Int
0 then forall a. Maybe a
Nothing else forall a. a -> Maybe a
Just (forall a. Vector a -> a
DV.head Vector Word8
s, forall v. Drop v => Count -> v -> v
drop Count
1 Vector Word8
s)
  {-# INLINE uncons   #-}

instance Uncons (DV.Vector Word16) where
  uncons :: Vector Word16 -> Maybe (Elem (Vector Word16), Vector Word16)
uncons Vector Word16
s = if forall a. Vector a -> Int
DV.length Vector Word16
s forall a. Eq a => a -> a -> Bool
== Int
0 then forall a. Maybe a
Nothing else forall a. a -> Maybe a
Just (forall a. Vector a -> a
DV.head Vector Word16
s, forall v. Drop v => Count -> v -> v
drop Count
1 Vector Word16
s)
  {-# INLINE uncons   #-}

instance Uncons (DV.Vector Word32) where
  uncons :: Vector Word32 -> Maybe (Elem (Vector Word32), Vector Word32)
uncons Vector Word32
s = if forall a. Vector a -> Int
DV.length Vector Word32
s forall a. Eq a => a -> a -> Bool
== Int
0 then forall a. Maybe a
Nothing else forall a. a -> Maybe a
Just (forall a. Vector a -> a
DV.head Vector Word32
s, forall v. Drop v => Count -> v -> v
drop Count
1 Vector Word32
s)
  {-# INLINE uncons   #-}

instance Uncons (DV.Vector Word64) where
  uncons :: Vector Count -> Maybe (Elem (Vector Count), Vector Count)
uncons Vector Count
s = if forall a. Vector a -> Int
DV.length Vector Count
s forall a. Eq a => a -> a -> Bool
== Int
0 then forall a. Maybe a
Nothing else forall a. a -> Maybe a
Just (forall a. Vector a -> a
DV.head Vector Count
s, forall v. Drop v => Count -> v -> v
drop Count
1 Vector Count
s)
  {-# INLINE uncons   #-}

instance Uncons (DVS.Vector Word8) where
  uncons :: Vector Word8 -> Maybe (Elem (Vector Word8), Vector Word8)
uncons Vector Word8
s = if forall a. Storable a => Vector a -> Int
DVS.length Vector Word8
s forall a. Eq a => a -> a -> Bool
== Int
0 then forall a. Maybe a
Nothing else forall a. a -> Maybe a
Just (forall a. Storable a => Vector a -> a
DVS.head Vector Word8
s, forall v. Drop v => Count -> v -> v
drop Count
1 Vector Word8
s)
  {-# INLINE uncons   #-}

instance Uncons (DVS.Vector Word16) where
  uncons :: Vector Word16 -> Maybe (Elem (Vector Word16), Vector Word16)
uncons Vector Word16
s = if forall a. Storable a => Vector a -> Int
DVS.length Vector Word16
s forall a. Eq a => a -> a -> Bool
== Int
0 then forall a. Maybe a
Nothing else forall a. a -> Maybe a
Just (forall a. Storable a => Vector a -> a
DVS.head Vector Word16
s, forall v. Drop v => Count -> v -> v
drop Count
1 Vector Word16
s)
  {-# INLINE uncons   #-}

instance Uncons (DVS.Vector Word32) where
  uncons :: Vector Word32 -> Maybe (Elem (Vector Word32), Vector Word32)
uncons Vector Word32
s = if forall a. Storable a => Vector a -> Int
DVS.length Vector Word32
s forall a. Eq a => a -> a -> Bool
== Int
0 then forall a. Maybe a
Nothing else forall a. a -> Maybe a
Just (forall a. Storable a => Vector a -> a
DVS.head Vector Word32
s, forall v. Drop v => Count -> v -> v
drop Count
1 Vector Word32
s)
  {-# INLINE uncons   #-}

instance Uncons (DVS.Vector Word64) where
  uncons :: Vector Count -> Maybe (Elem (Vector Count), Vector Count)
uncons Vector Count
s = if forall a. Storable a => Vector a -> Int
DVS.length Vector Count
s forall a. Eq a => a -> a -> Bool
== Int
0 then forall a. Maybe a
Nothing else forall a. a -> Maybe a
Just (forall a. Storable a => Vector a -> a
DVS.head Vector Count
s, forall v. Drop v => Count -> v -> v
drop Count
1 Vector Count
s)
  {-# INLINE uncons   #-}

instance Uncons (DV.Vector Int8) where
  uncons :: Vector Int8 -> Maybe (Elem (Vector Int8), Vector Int8)
uncons Vector Int8
s = if forall a. Vector a -> Int
DV.length Vector Int8
s forall a. Eq a => a -> a -> Bool
== Int
0 then forall a. Maybe a
Nothing else forall a. a -> Maybe a
Just (forall a. Vector a -> a
DV.head Vector Int8
s, forall v. Drop v => Count -> v -> v
drop Count
1 Vector Int8
s)
  {-# INLINE uncons   #-}

instance Uncons (DV.Vector Int16) where
  uncons :: Vector Int16 -> Maybe (Elem (Vector Int16), Vector Int16)
uncons Vector Int16
s = if forall a. Vector a -> Int
DV.length Vector Int16
s forall a. Eq a => a -> a -> Bool
== Int
0 then forall a. Maybe a
Nothing else forall a. a -> Maybe a
Just (forall a. Vector a -> a
DV.head Vector Int16
s, forall v. Drop v => Count -> v -> v
drop Count
1 Vector Int16
s)
  {-# INLINE uncons   #-}

instance Uncons (DV.Vector Int32) where
  uncons :: Vector Int32 -> Maybe (Elem (Vector Int32), Vector Int32)
uncons Vector Int32
s = if forall a. Vector a -> Int
DV.length Vector Int32
s forall a. Eq a => a -> a -> Bool
== Int
0 then forall a. Maybe a
Nothing else forall a. a -> Maybe a
Just (forall a. Vector a -> a
DV.head Vector Int32
s, forall v. Drop v => Count -> v -> v
drop Count
1 Vector Int32
s)
  {-# INLINE uncons   #-}

instance Uncons (DV.Vector Int64) where
  uncons :: Vector Int64 -> Maybe (Elem (Vector Int64), Vector Int64)
uncons Vector Int64
s = if forall a. Vector a -> Int
DV.length Vector Int64
s forall a. Eq a => a -> a -> Bool
== Int
0 then forall a. Maybe a
Nothing else forall a. a -> Maybe a
Just (forall a. Vector a -> a
DV.head Vector Int64
s, forall v. Drop v => Count -> v -> v
drop Count
1 Vector Int64
s)
  {-# INLINE uncons   #-}

instance Uncons (DVS.Vector Int8) where
  uncons :: Vector Int8 -> Maybe (Elem (Vector Int8), Vector Int8)
uncons Vector Int8
s = if forall a. Storable a => Vector a -> Int
DVS.length Vector Int8
s forall a. Eq a => a -> a -> Bool
== Int
0 then forall a. Maybe a
Nothing else forall a. a -> Maybe a
Just (forall a. Storable a => Vector a -> a
DVS.head Vector Int8
s, forall v. Drop v => Count -> v -> v
drop Count
1 Vector Int8
s)
  {-# INLINE uncons   #-}

instance Uncons (DVS.Vector Int16) where
  uncons :: Vector Int16 -> Maybe (Elem (Vector Int16), Vector Int16)
uncons Vector Int16
s = if forall a. Storable a => Vector a -> Int
DVS.length Vector Int16
s forall a. Eq a => a -> a -> Bool
== Int
0 then forall a. Maybe a
Nothing else forall a. a -> Maybe a
Just (forall a. Storable a => Vector a -> a
DVS.head Vector Int16
s, forall v. Drop v => Count -> v -> v
drop Count
1 Vector Int16
s)
  {-# INLINE uncons   #-}

instance Uncons (DVS.Vector Int32) where
  uncons :: Vector Int32 -> Maybe (Elem (Vector Int32), Vector Int32)
uncons Vector Int32
s = if forall a. Storable a => Vector a -> Int
DVS.length Vector Int32
s forall a. Eq a => a -> a -> Bool
== Int
0 then forall a. Maybe a
Nothing else forall a. a -> Maybe a
Just (forall a. Storable a => Vector a -> a
DVS.head Vector Int32
s, forall v. Drop v => Count -> v -> v
drop Count
1 Vector Int32
s)
  {-# INLINE uncons   #-}

instance Uncons (DVS.Vector Int64) where
  uncons :: Vector Int64 -> Maybe (Elem (Vector Int64), Vector Int64)
uncons Vector Int64
s = if forall a. Storable a => Vector a -> Int
DVS.length Vector Int64
s forall a. Eq a => a -> a -> Bool
== Int
0 then forall a. Maybe a
Nothing else forall a. a -> Maybe a
Just (forall a. Storable a => Vector a -> a
DVS.head Vector Int64
s, forall v. Drop v => Count -> v -> v
drop Count
1 Vector Int64
s)
  {-# INLINE uncons   #-}

instance Uncons (DVS.Vector Int) where
  uncons :: Vector Int -> Maybe (Elem (Vector Int), Vector Int)
uncons Vector Int
s = if forall a. Storable a => Vector a -> Int
DVS.length Vector Int
s forall a. Eq a => a -> a -> Bool
== Int
0 then forall a. Maybe a
Nothing else forall a. a -> Maybe a
Just (forall a. Storable a => Vector a -> a
DVS.head Vector Int
s, forall v. Drop v => Count -> v -> v
drop Count
1 Vector Int
s)
  {-# INLINE uncons   #-}