```module Numeric.YHSeq.V0110.Type
( Seq
, Index
, Diff
, ParentIndex
, ParentList
, Depth
, DPNTuple
, DPN
, Class
, length
, lengthSeq
, lengthDPN
, index
, index1
, idx
, indexSeq
, indexDPN
, indexD
, indexP
, indexN
, indexPList
, slice
, slice1
, sliceSeq
, sliceDPN
, dropLast
) where

import Prelude hiding (length)

type Seq = [Integer]

type Index = Integer

type Diff = Integer

type ParentIndex = Index

type ParentList = [ParentIndex]

type Depth = Integer

type DPNTuple = (Diff, ParentList, Depth)

type DPN = [DPNTuple]

type Class = Integer

length :: [a] -> Integer
length []      = 0
length (_ : s) = length s + 1

lengthSeq :: Seq -> Integer
lengthSeq = length

lengthDPN :: DPN -> Integer
lengthDPN = length

index :: [a] -> Integer -> a
index x n = if n < 0
then error "index: negative index"
else index' x n

index' :: [a] -> Integer -> a
index' x n = case x of
[]      -> error "index: index too large"
xv : xs -> if n == 0
then xv
else index' xs (n - 1)

index1 :: [a] -> Integer -> a
index1 x n = if n < 1
then error "index1: non-positive index"
else index1' x n

index1' :: [a] -> Integer -> a
index1' x n = case x of
[]      -> error "index1: index too large"
xv : xs -> if n == 1
then xv
else index1' xs (n - 1)

idx :: [a] -> Integer -> a
idx x n = if n < 0
then error "idx: negative index"
else case x of
[]      -> error "idx: empty list"
xv : xs -> idx' xv xs n

idx' :: a -> [a] -> Integer -> a
idx' a x n = if n == 0
then a
else case x of
[]      -> a
xv : xs -> idx' xv xs (n - 1)

indexSeq :: Seq -> Index -> Integer
indexSeq = index1

indexDPN :: DPN -> Index -> DPNTuple
indexDPN = index1

indexD :: DPN -> Index -> Diff
indexD x n = case indexDPN x n of { (d, _, _) -> d }

indexP :: DPN -> Index -> ParentList
indexP x n = case indexDPN x n of { (_, p, _) -> p }

indexN :: DPN -> Index -> Depth
indexN x n = case indexDPN x n of { (_, _, n) -> n }

indexPList :: ParentList -> Index -> ParentIndex
indexPList = index

slice :: Integer -> Integer -> [a] -> [a]
slice a b x = slice' a b x 0
-- slice a b x =
--   map fst \$
--     filter (\x -> let n = snd x in a <= n && n <= b) \$
--       zipWith (,) x [0..]

slice' :: Integer -> Integer -> [a] -> Integer -> [a]
slice' a b x n = case x of
[]      -> []
xv : xs -> if a <= n && n <= b
then xv : slice' a b xs (n + 1)
else slice' a b xs (n + 1)

slice1 :: Integer -> Integer -> [a] -> [a]
slice1 a b x = slice1' a b x 1

slice1' :: Integer -> Integer -> [a] -> Integer -> [a]
slice1' a b x n = case x of
[]      -> []
xv : xs -> if a <= n && n <= b
then xv : slice1' a b xs (n + 1)
else slice1' a b xs (n + 1)

sliceSeq :: Integer -> Integer -> Seq -> Seq
sliceSeq = slice1

sliceDPN :: Integer -> Integer -> DPN -> DPN
sliceDPN = slice1

dropLast :: [a] -> [a]
dropLast x = case x of
[]      -> error "dropLast: empty list"
xv : xs -> dropLast' xv xs

dropLast' :: a -> [a] -> [a]
dropLast' xv xs = case xs of
[]        -> []
xsv : xss -> xv : dropLast' xsv xss
```