diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,8 +3,25 @@
 `slist` uses [PVP Versioning][1].
 The changelog is available [on GitHub][2].
 
-0.0.0
-=====
+## 0.1.0.0
+
+* [#13](https://github.com/vrom911/slist/issues/13):
+  Support GHC-8.8.1.
+* [#16](https://github.com/vrom911/slist/issues/16):
+  Use `DerivingStrategies`.
+* [#9](https://github.com/vrom911/slist/issues/9):
+  Implement `fromRange` function.
+  (by @zfnmxt)
+* [#6](https://github.com/vrom911/slist/issues/6):
+  Add generic function over the size and indices.
+  (by @waynee95)
+* Make `dropWhile` work better on infinite lists.
+  (by @chshersh)
+* Support GHC-8.6.5 instead os GHC-8.6.3.
+* [#6](https://github.com/vrom911/slist/issues/6):
+  Build with Stack.
+
+## 0.0.0
 
 * Initially created.
 
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,8 +1,10 @@
 # slist
 
-[![Hackage](https://img.shields.io/hackage/v/slist.svg)](https://hackage.haskell.org/package/slist)
+[![Build status](https://img.shields.io/travis/vrom911/slist.svg?logo=travis)](https://travis-ci.org/vrom911/slist)
+[![Hackage](https://img.shields.io/hackage/v/slist.svg?logo=haskell)](https://hackage.haskell.org/package/slist)
+[![Stackage LTS](http://stackage.org/package/slist/badge/lts)](http://stackage.org/lts/package/slist)
+[![Stackage Nightly](http://stackage.org/package/slist/badge/nightly)](http://stackage.org/nightly/package/slist)
 [![MPL-2.0 license](https://img.shields.io/badge/license-MPL--2.0-blue.svg)](LICENSE)
-[![Build status](https://secure.travis-ci.org/vrom911/slist.svg)](https://travis-ci.org/vrom911/slist)
 
 This package introduces sized list data type — `Slist`. The data type
 has the following shape:
@@ -14,7 +16,7 @@
     }
 ```
 
-As you can see along with the familiar list, it contains `Size` field that
+As you can see that along with the familiar list, it contains `Size` field that
 represents the size of the structure. Slists can be finite or infinite, and this
 is expressed with `Size`.
 
@@ -41,7 +43,7 @@
 |-------------------|-----------------------------------|-----------------------------|----------------------------------------|------------------|
 | `length`          | `O(n)`                            | <_hangs_>                   | `O(1)`                                 | `O(1)`           |
 | `safeLast`        | `O(n)`                            | <_hangs_>                   | `O(n)`                                 | `O(1)`           |
-| `init`            | `O(n)`                            | <_hangs_>                   | `O(n)`                                 | `O(1)`           |
+| `init`            | `O(n)`                            | <_works infinitely_>        | `O(n)`                                 | `O(1)`           |
 | `take`            | `O(min i n)`                      | `O(i)`                      | `0 < i < n`: `O(i)`; otherwise: `O(1)` | `O(i)`           |
 | `at`              | `O(min i n)` (run-time exception) | `O(i)` (run-time exception) | `0 < i < n`: `O(i)`; otherwise: `O(1)` | `O(i)`           |
 | `safeStripPrefix` | `O(m)`                            | `O(m)` (can hang)           | `O(m)`                                 | `O(m)`           |
diff --git a/slist.cabal b/slist.cabal
--- a/slist.cabal
+++ b/slist.cabal
@@ -1,6 +1,6 @@
-cabal-version:       2.0
+cabal-version:       2.4
 name:                slist
-version:             0.0.0
+version:             0.1.0.0
 synopsis:            Sized list
 description:         This package implements @Slist@ data structure that stores the size
                      of the list along with the list itself.
@@ -17,18 +17,15 @@
                    , CHANGELOG.md
 tested-with:         GHC == 8.2.2
                    , GHC == 8.4.4
-                   , GHC == 8.6.3
+                   , GHC == 8.6.5
+                   , GHC == 8.8.1
 
 source-repository head
   type:                git
   location:            https://github.com/vrom911/slist.git
 
-library
-  hs-source-dirs:      src
-  exposed-modules:     Slist
-                         Slist.Size
-
-  build-depends:       base >= 4.10.1.0 && < 4.13
+common common-options
+  build-depends:       base >= 4.10.1.0 && < 4.14
 
   ghc-options:         -Wall
                        -Wincomplete-uni-patterns
@@ -37,10 +34,13 @@
                        -Widentities
                        -Wredundant-constraints
                        -fhide-source-paths
+  if impl(ghc >= 8.8.1)
+    ghc-options:       -Wmissing-deriving-strategies
+                       -Werror=missing-deriving-strategies
 
-  default-language:    Haskell2010
   default-extensions:  ConstraintKinds
                        DeriveGeneric
+                       DerivingStrategies
                        GeneralizedNewtypeDeriving
                        InstanceSigs
                        KindSignatures
@@ -53,48 +53,33 @@
                        TypeApplications
                        ViewPatterns
 
+  default-language:    Haskell2010
+
+library
+  import:              common-options
+  hs-source-dirs:      src
+  exposed-modules:     Slist
+                         Slist.Size
+
 test-suite slist-test
+  import:              common-options
   type:                exitcode-stdio-1.0
   hs-source-dirs:      test
   main-is:             Spec.hs
 
-  build-depends:       base >= 4.10.1.0 && < 4.13
-                     , slist
+  build-depends:       slist
 
-  ghc-options:         -Wall
-                       -threaded
+  ghc-options:         -threaded
                        -rtsopts
                        -with-rtsopts=-N
-                       -Wincomplete-uni-patterns
-                       -Wincomplete-record-updates
-                       -Wcompat
-                       -Widentities
-                       -Wredundant-constraints
-                       -fhide-source-paths
 
-  default-language:    Haskell2010
-  default-extensions:  ConstraintKinds
-                       DeriveGeneric
-                       GeneralizedNewtypeDeriving
-                       InstanceSigs
-                       KindSignatures
-                       LambdaCase
-                       OverloadedStrings
-                       RecordWildCards
-                       ScopedTypeVariables
-                       StandaloneDeriving
-                       TupleSections
-                       TypeApplications
-                       ViewPatterns
-
 test-suite slist-doctest
+  import:              common-options
   type:                exitcode-stdio-1.0
   hs-source-dirs:      test
   main-is:             Doctest.hs
 
-  build-depends:       base >= 4.9 && < 5
-                     , doctest
+  build-depends:       doctest
                      , Glob
 
   ghc-options:         -threaded
-  default-language:    Haskell2010
diff --git a/src/Slist.hs b/src/Slist.hs
--- a/src/Slist.hs
+++ b/src/Slist.hs
@@ -1,7 +1,10 @@
 {-# LANGUAGE BangPatterns #-}
 {-# LANGUAGE CPP          #-}
 {-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE ViewPatterns #-}
 
+{- HLINT ignore "Use mconcat" -}
+
 {- |
 Copyright:  (c) 2019 vrom911
 License:    MPL-2.0
@@ -86,6 +89,7 @@
        , repeat
        , replicate
        , cycle
+       , fromRange
          -- * Basic functions
        , len
        , size
@@ -190,6 +194,15 @@
        , sortOn
        , insert
        , insertBy
+
+        -- * Generic functions
+       , genericLength
+       , genericTake
+       , genericDrop
+       , genericSplitAt
+       , genericAt
+       , genericUnsafeAt
+       , genericReplicate
        ) where
 
 import Control.Applicative (Alternative (empty, (<|>)), liftA2)
@@ -216,7 +229,7 @@
 data Slist a = Slist
     { sList :: [a]
     , sSize :: Size
-    } deriving (Show, Read)
+    } deriving stock (Show, Read)
 
 {- | Equality of sized lists is checked more efficiently
 due to the fact that the check on the list sizes can be
@@ -345,7 +358,7 @@
 
 instance Traversable Slist where
     traverse :: (Applicative f) => (a -> f b) -> Slist a -> f (Slist b)
-    traverse f (Slist l s) = (\x -> Slist x s) <$> traverse f l
+    traverse f (Slist l s) = (`Slist` s) <$> traverse f l
     {-# INLINE traverse #-}
 
 instance L.IsList (Slist a) where
@@ -490,6 +503,25 @@
 cycle Slist{..}             = infiniteSlist $ L.cycle sList
 {-# INLINE cycle #-}
 
+{- | @O(1)@. An slist equivalent of 'P.enumFromTo' function or @[from..to]@ notation:
+creates an 'Slist' of sequentially ordered values starting at @from@ and ending at @to@ inclusively.
+
+>>> fromRange 0 5
+Slist {sList = [0,1,2,3,4,5], sSize = Size 6}
+>>> fromRange 5 0
+Slist {sList = [], sSize = Size 0}
+>>> fromRange 0 0
+Slist {sList = [0], sSize = Size 1}
+>>> fromRange 'a' 'd'
+Slist {sList = "abcd", sSize = Size 4}
+-}
+fromRange :: Enum a => a -> a -> Slist a
+fromRange from to = Slist [from..to] s
+  where
+    s :: Size
+    s = Size $ max 0 (fromEnum to - fromEnum from + 1)
+{-# INLINE fromRange #-}
+
 ----------------------------------------------------------------------------
 -- Basic functions
 ----------------------------------------------------------------------------
@@ -798,7 +830,7 @@
 -}
 permutations :: Slist a -> Slist (Slist a)
 permutations (Slist l s) = Slist
-    { sList = P.map (\a -> Slist a s) $ L.permutations l
+    { sList = P.map (`Slist` s) $ L.permutations l
     , sSize = fact s
     }
   where
@@ -1053,8 +1085,14 @@
 Slist {sList = [1,2,3,4,5,6,7,8,9,10], sSize = Size 10}
 >>> take 5 $ dropWhile (<3) $ infiniteSlist [1..]
 Slist {sList = [3,4,5,6,7], sSize = Size 5}
+
+@
+>> __dropWhile (< 5) $ 'infiniteSlist' [1..]__
+Slist {sList = [5,6..], sSize = 'Infinity'}
+@
 -}
 dropWhile :: forall a . (a -> Bool) -> Slist a -> Slist a
+dropWhile p (Slist l Infinity) = Slist (P.dropWhile p l) Infinity
 dropWhile p Slist{..} = let (s, l) = go 0 sList in
     Slist l (sSize - Size s)
   where
@@ -1236,7 +1274,7 @@
 isPrefixOf :: Eq a => Slist a -> Slist a -> Bool
 isPrefixOf (Slist l1 s1) (Slist l2 s2)
     | s1 > s2 = False
-    | otherwise = L.isPrefixOf l1 l2
+    | otherwise = l1 `L.isPrefixOf` l2
 {-# INLINE isPrefixOf #-}
 
 {- | Similar to 'isPrefixOf', but never hangs on infinite lists
@@ -1250,7 +1288,7 @@
 safeIsPrefixOf :: Eq a => Slist a -> Slist a -> Bool
 safeIsPrefixOf sl1@(Slist _ s1) sl2@(Slist _ s2)
     | s1 == Infinity && s2 == Infinity = False
-    | otherwise = isPrefixOf sl1 sl2
+    | otherwise = sl1 `isPrefixOf` sl2
 {-# INLINE safeIsPrefixOf #-}
 
 {- |
@@ -1276,7 +1314,7 @@
 isSuffixOf :: Eq a => Slist a -> Slist a -> Bool
 isSuffixOf (Slist l1 s1) (Slist l2 s2)
     | s1 > s2 = False
-    | otherwise = L.isSuffixOf l1 l2
+    | otherwise = l1 `L.isSuffixOf` l2
 {-# INLINE isSuffixOf #-}
 
 {- | Similar to 'isSuffixOf', but never hangs on infinite lists
@@ -1290,7 +1328,7 @@
 safeIsSuffixOf :: Eq a => Slist a -> Slist a -> Bool
 safeIsSuffixOf sl1 sl2@(Slist _ s2)
     | s2 == Infinity = False
-    | otherwise = isSuffixOf sl1 sl2
+    | otherwise = sl1 `isSuffixOf` sl2
 {-# INLINE safeIsSuffixOf #-}
 
 {- |
@@ -1316,7 +1354,7 @@
 isInfixOf :: Eq a => Slist a -> Slist a -> Bool
 isInfixOf (Slist l1 s1) (Slist l2 s2)
     | s1 > s2 = False
-    | otherwise = L.isInfixOf l1 l2
+    | otherwise = l1 `L.isInfixOf` l2
 {-# INLINE isInfixOf #-}
 
 {- | Similar to 'isInfixOf', but never hangs on infinite lists
@@ -1330,7 +1368,7 @@
 safeIsInfixOf :: Eq a => Slist a -> Slist a -> Bool
 safeIsInfixOf sl1@(Slist _ s1) sl2@(Slist _ s2)
     | s1 == Infinity && s2 == Infinity = False
-    | otherwise = isInfixOf sl1 sl2
+    | otherwise = sl1 `isInfixOf` sl2
 {-# INLINE safeIsInfixOf #-}
 
 {- |
@@ -1866,3 +1904,163 @@
 insertBy :: (a -> a -> Ordering) -> a -> Slist a -> Slist a
 insertBy f a Slist{..} = Slist (L.insertBy f a sList) (sSize + 1)
 {-# INLINE insertBy #-}
+
+----------------------------------------------------------------------------
+-- Generic fuctions
+----------------------------------------------------------------------------
+
+{- | @O(1)@.
+The 'genericLength' function is an overloaded version of 'length'.
+In particular, instead of returning an 'Int', it returns any type which is an
+instance of 'Num'.
+
+>>> genericLength $ one 42
+1
+>>> genericLength $ slist [1..3]
+3
+>>> genericLength $ infiniteSlist [1..]
+9223372036854775807
+-}
+genericLength :: Num i => Slist a -> i
+genericLength = fromIntegral . length
+{-# INLINE genericLength #-}
+
+{- | @O(i) | i < n@ and @O(1) | otherwise@.
+The 'genericTake' function is an overloaded version of 'take', which
+accepts any 'Integral' value as the number of elements to take.
+
+>>> genericTake 5 $ slist "Hello world!"
+Slist {sList = "Hello", sSize = Size 5}
+>>> genericTake 20 $ slist "small"
+Slist {sList = "small", sSize = Size 5}
+>>> genericTake 0 $ slist "none"
+Slist {sList = "", sSize = Size 0}
+>>> genericTake (-11) $ slist "hmm"
+Slist {sList = "", sSize = Size 0}
+>>> genericTake 4 $ infiniteSlist [1..]
+Slist {sList = [1,2,3,4], sSize = Size 4}
+-}
+genericTake :: Integral i => i -> Slist a -> Slist a
+genericTake (fromIntegral -> i) sl@Slist{..}
+    | Size i >= sSize = sl
+    | i <= 0 = mempty
+    | otherwise = Slist
+        { sList = L.genericTake i sList
+        , sSize = min sSize (Size i)
+        }
+{-# INLINE genericTake #-}
+
+{- | @O(i) | i < n@ and @O(1) | otherwise@.
+The 'genericDrop' function is an overloaded version of 'drop', which accepts
+any 'Integral' value as the number of elements to drop.
+
+>>> genericDrop 6 $ slist "Hello World"
+Slist {sList = "World", sSize = Size 5}
+>>> genericDrop 42 $ slist "oops!"
+Slist {sList = "", sSize = Size 0}
+>>> genericDrop 0 $ slist "Hello World!"
+Slist {sList = "Hello World!", sSize = Size 12}
+>>> genericDrop (-4) $ one 42
+Slist {sList = [42], sSize = Size 1}
+
+@
+>> __drop 5 $ 'infiniteSlist' [1..]__
+Slist {sList = [6..], sSize = 'Infinity'}
+@
+
+-}
+genericDrop :: Integral i => i -> Slist a -> Slist a
+genericDrop (fromIntegral -> i) sl@Slist{..}
+    | i <= 0 = sl
+    | Size i >= sSize = mempty
+    | otherwise = Slist
+        { sList = L.genericDrop i sList
+        , sSize = sSize - Size i
+        }
+{-# INLINE genericDrop #-}
+
+{- | @O(i) | i < n@ and @O(1) | otherwise@.
+The 'genericSplitAt' function is an overloaded version of 'splitAt', which
+accepts any 'Integral' value as the position at which to split.
+
+>>> genericSplitAt 5 $ slist "Hello World!"
+(Slist {sList = "Hello", sSize = Size 5},Slist {sList = " World!", sSize = Size 7})
+>>> genericSplitAt 0 $ slist "abc"
+(Slist {sList = "", sSize = Size 0},Slist {sList = "abc", sSize = Size 3})
+>>> genericSplitAt 4 $ slist "abc"
+(Slist {sList = "abc", sSize = Size 3},Slist {sList = "", sSize = Size 0})
+>>> genericSplitAt (-42) $ slist "??"
+(Slist {sList = "", sSize = Size 0},Slist {sList = "??", sSize = Size 2})
+
+@
+>> __genericSplitAt 2 $ 'infiniteSlist' [1..]__
+(Slist {sList = [1,2], sSize = 'Size' 2}, Slist {sList = [3..], sSize = 'Infinity'})
+@
+
+-}
+genericSplitAt :: Integral i => i -> Slist a -> (Slist a, Slist a)
+genericSplitAt (fromIntegral -> i) sl@Slist{..}
+    | i <= 0 = (mempty, sl)
+    | Size i >= sSize = (sl, mempty)
+    | otherwise =
+      let (l1, l2) = L.genericSplitAt i sList
+          s2 = sSize - Size i
+      in (Slist l1 $ Size i, Slist l2 s2)
+{-# INLINE genericSplitAt #-}
+
+{- | @O(i) | i < n@ and @O(1) | otherwise@.
+The 'genericAt' function is an overloaded version of 'at', which
+accepts any 'Integral' value as the position. If the element on the given
+position does not exist it will return 'Nothing'.
+
+>>> let sl = slist [1..10]
+>>> genericAt 0 sl
+Just 1
+>>> genericAt (-1) sl
+Nothing
+>>> genericAt 11 sl
+Nothing
+>>> genericAt 9 sl
+Just 10
+-}
+genericAt :: Integral i => i -> Slist a -> Maybe a
+genericAt = at . fromIntegral
+{-# INLINE genericAt #-}
+
+{- | @O(min i n)@.
+The 'genericUnsafeAt' function is an overloaded version of 'unsafeAt', which
+accepts any 'Integral' value as the position. If the element on the given
+position does not exist it throws the exception at run-time.
+
+>>> let sl = slist [1..10]
+>>> genericUnsafeAt 0 sl
+1
+>>> genericUnsafeAt (-1) sl
+*** Exception: Slist.genericUnsafeAt: negative argument
+>>> genericUnsafeAt 11 sl
+*** Exception: Slist.genericUnsafeAt: index too large
+>>> genericUnsafeAt 9 sl
+10
+-}
+genericUnsafeAt :: Integral i => i -> Slist a -> a
+genericUnsafeAt i _ | i < 0 = errorWithoutStackTrace "Slist.genericUnsafeAt: negative argument"
+genericUnsafeAt i (Slist l Infinity) = L.genericIndex l i
+genericUnsafeAt i (Slist l (Size n))
+    | i >= fromIntegral n = errorWithoutStackTrace "Slist.genericUnsafeAt: index too large"
+    | otherwise = L.genericIndex l i
+{-# INLINE genericUnsafeAt #-}
+
+{- | @O(n)@.
+The 'genericReplicate' function is an overloaded version of 'replicate',
+which accepts any 'Integral' value as the number of repetitions to make.
+
+>>> genericReplicate 3 'o'
+Slist {sList = "ooo", sSize = Size 3}
+>>> genericReplicate (-11) "hmm"
+Slist {sList = [], sSize = Size 0}
+-}
+genericReplicate :: Integral i => i -> a -> Slist a
+genericReplicate n x
+    | n <= 0 = mempty
+    | otherwise = Slist (L.genericReplicate n x) $ Size (fromIntegral n)
+{-# INLINE genericReplicate #-}
diff --git a/src/Slist/Size.hs b/src/Slist/Size.hs
--- a/src/Slist/Size.hs
+++ b/src/Slist/Size.hs
@@ -26,7 +26,7 @@
     = Size !Int
     -- | Infinite size.
     | Infinity
-    deriving (Show, Read, Eq, Ord)
+    deriving stock (Show, Read, Eq, Ord)
 
 {- | Efficient implementations of numeric operations with 'Size's.
 
diff --git a/test/Doctest.hs b/test/Doctest.hs
--- a/test/Doctest.hs
+++ b/test/Doctest.hs
@@ -10,4 +10,5 @@
         $ "-XInstanceSigs"
         : "-XScopedTypeVariables"
         : "-XRecordWildCards"
+        : "-XDerivingStrategies"
         : sourceFiles
