{-# 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) -> (Char, String) -> Maybe (Char, String)
forall a. a -> Maybe a
Just (Char
x, String
xs)
    String
_      -> Maybe (Elem String, String)
forall a. Maybe a
Nothing
  {-# INLINE uncons   #-}

instance Uncons BS.ByteString where
  uncons :: ByteString -> Maybe (Elem ByteString, ByteString)
uncons = ByteString -> Maybe (Word8, ByteString)
ByteString -> Maybe (Elem ByteString, 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 Vector Word8 -> Int
forall a. Vector a -> Int
DV.length Vector Word8
s Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then Maybe (Elem (Vector Word8), Vector Word8)
forall a. Maybe a
Nothing else (Word8, Vector Word8) -> Maybe (Word8, Vector Word8)
forall a. a -> Maybe a
Just (Vector Word8 -> Word8
forall a. Vector a -> a
DV.head Vector Word8
s, Count -> Vector Word8 -> Vector Word8
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 Vector Word16 -> Int
forall a. Vector a -> Int
DV.length Vector Word16
s Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then Maybe (Elem (Vector Word16), Vector Word16)
forall a. Maybe a
Nothing else (Word16, Vector Word16) -> Maybe (Word16, Vector Word16)
forall a. a -> Maybe a
Just (Vector Word16 -> Word16
forall a. Vector a -> a
DV.head Vector Word16
s, Count -> Vector Word16 -> Vector Word16
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 Vector Word32 -> Int
forall a. Vector a -> Int
DV.length Vector Word32
s Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then Maybe (Elem (Vector Word32), Vector Word32)
forall a. Maybe a
Nothing else (Word32, Vector Word32) -> Maybe (Word32, Vector Word32)
forall a. a -> Maybe a
Just (Vector Word32 -> Word32
forall a. Vector a -> a
DV.head Vector Word32
s, Count -> Vector Word32 -> Vector Word32
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 Vector Count -> Int
forall a. Vector a -> Int
DV.length Vector Count
s Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then Maybe (Elem (Vector Count), Vector Count)
forall a. Maybe a
Nothing else (Count, Vector Count) -> Maybe (Count, Vector Count)
forall a. a -> Maybe a
Just (Vector Count -> Count
forall a. Vector a -> a
DV.head Vector Count
s, Count -> Vector Count -> Vector Count
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 Vector Word8 -> Int
forall a. Storable a => Vector a -> Int
DVS.length Vector Word8
s Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then Maybe (Elem (Vector Word8), Vector Word8)
forall a. Maybe a
Nothing else (Word8, Vector Word8) -> Maybe (Word8, Vector Word8)
forall a. a -> Maybe a
Just (Vector Word8 -> Word8
forall a. Storable a => Vector a -> a
DVS.head Vector Word8
s, Count -> Vector Word8 -> Vector Word8
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 Vector Word16 -> Int
forall a. Storable a => Vector a -> Int
DVS.length Vector Word16
s Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then Maybe (Elem (Vector Word16), Vector Word16)
forall a. Maybe a
Nothing else (Word16, Vector Word16) -> Maybe (Word16, Vector Word16)
forall a. a -> Maybe a
Just (Vector Word16 -> Word16
forall a. Storable a => Vector a -> a
DVS.head Vector Word16
s, Count -> Vector Word16 -> Vector Word16
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 Vector Word32 -> Int
forall a. Storable a => Vector a -> Int
DVS.length Vector Word32
s Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then Maybe (Elem (Vector Word32), Vector Word32)
forall a. Maybe a
Nothing else (Word32, Vector Word32) -> Maybe (Word32, Vector Word32)
forall a. a -> Maybe a
Just (Vector Word32 -> Word32
forall a. Storable a => Vector a -> a
DVS.head Vector Word32
s, Count -> Vector Word32 -> Vector Word32
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 Vector Count -> Int
forall a. Storable a => Vector a -> Int
DVS.length Vector Count
s Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then Maybe (Elem (Vector Count), Vector Count)
forall a. Maybe a
Nothing else (Count, Vector Count) -> Maybe (Count, Vector Count)
forall a. a -> Maybe a
Just (Vector Count -> Count
forall a. Storable a => Vector a -> a
DVS.head Vector Count
s, Count -> Vector Count -> Vector Count
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 Vector Int8 -> Int
forall a. Vector a -> Int
DV.length Vector Int8
s Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then Maybe (Elem (Vector Int8), Vector Int8)
forall a. Maybe a
Nothing else (Int8, Vector Int8) -> Maybe (Int8, Vector Int8)
forall a. a -> Maybe a
Just (Vector Int8 -> Int8
forall a. Vector a -> a
DV.head Vector Int8
s, Count -> Vector Int8 -> Vector Int8
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 Vector Int16 -> Int
forall a. Vector a -> Int
DV.length Vector Int16
s Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then Maybe (Elem (Vector Int16), Vector Int16)
forall a. Maybe a
Nothing else (Int16, Vector Int16) -> Maybe (Int16, Vector Int16)
forall a. a -> Maybe a
Just (Vector Int16 -> Int16
forall a. Vector a -> a
DV.head Vector Int16
s, Count -> Vector Int16 -> Vector Int16
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 Vector Int32 -> Int
forall a. Vector a -> Int
DV.length Vector Int32
s Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then Maybe (Elem (Vector Int32), Vector Int32)
forall a. Maybe a
Nothing else (Int32, Vector Int32) -> Maybe (Int32, Vector Int32)
forall a. a -> Maybe a
Just (Vector Int32 -> Int32
forall a. Vector a -> a
DV.head Vector Int32
s, Count -> Vector Int32 -> Vector Int32
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 Vector Int64 -> Int
forall a. Vector a -> Int
DV.length Vector Int64
s Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then Maybe (Elem (Vector Int64), Vector Int64)
forall a. Maybe a
Nothing else (Int64, Vector Int64) -> Maybe (Int64, Vector Int64)
forall a. a -> Maybe a
Just (Vector Int64 -> Int64
forall a. Vector a -> a
DV.head Vector Int64
s, Count -> Vector Int64 -> Vector Int64
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 Vector Int8 -> Int
forall a. Storable a => Vector a -> Int
DVS.length Vector Int8
s Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then Maybe (Elem (Vector Int8), Vector Int8)
forall a. Maybe a
Nothing else (Int8, Vector Int8) -> Maybe (Int8, Vector Int8)
forall a. a -> Maybe a
Just (Vector Int8 -> Int8
forall a. Storable a => Vector a -> a
DVS.head Vector Int8
s, Count -> Vector Int8 -> Vector Int8
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 Vector Int16 -> Int
forall a. Storable a => Vector a -> Int
DVS.length Vector Int16
s Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then Maybe (Elem (Vector Int16), Vector Int16)
forall a. Maybe a
Nothing else (Int16, Vector Int16) -> Maybe (Int16, Vector Int16)
forall a. a -> Maybe a
Just (Vector Int16 -> Int16
forall a. Storable a => Vector a -> a
DVS.head Vector Int16
s, Count -> Vector Int16 -> Vector Int16
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 Vector Int32 -> Int
forall a. Storable a => Vector a -> Int
DVS.length Vector Int32
s Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then Maybe (Elem (Vector Int32), Vector Int32)
forall a. Maybe a
Nothing else (Int32, Vector Int32) -> Maybe (Int32, Vector Int32)
forall a. a -> Maybe a
Just (Vector Int32 -> Int32
forall a. Storable a => Vector a -> a
DVS.head Vector Int32
s, Count -> Vector Int32 -> Vector Int32
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 Vector Int64 -> Int
forall a. Storable a => Vector a -> Int
DVS.length Vector Int64
s Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then Maybe (Elem (Vector Int64), Vector Int64)
forall a. Maybe a
Nothing else (Int64, Vector Int64) -> Maybe (Int64, Vector Int64)
forall a. a -> Maybe a
Just (Vector Int64 -> Int64
forall a. Storable a => Vector a -> a
DVS.head Vector Int64
s, Count -> Vector Int64 -> Vector Int64
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 Vector Int -> Int
forall a. Storable a => Vector a -> Int
DVS.length Vector Int
s Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then Maybe (Elem (Vector Int), Vector Int)
forall a. Maybe a
Nothing else (Int, Vector Int) -> Maybe (Int, Vector Int)
forall a. a -> Maybe a
Just (Vector Int -> Int
forall a. Storable a => Vector a -> a
DVS.head Vector Int
s, Count -> Vector Int -> Vector Int
forall v. Drop v => Count -> v -> v
drop Count
1 Vector Int
s)
  {-# INLINE uncons   #-}