Write code to solve Scott Encoding in Haskell.

Scott encoding represents data as function that apply their argument (also a function) to their value. This approach is similar to using pattern matching on regular ADTs to extract and use their content.

You are given types representing the Scott encoding of four common Haskell types: Maybe, lists, Either and pairs (2-tuples).

Your task is to implement conversion functions between these regular types and their Scott encoding.

In addition, you will have to implement the following common operations using the provided Scott-encoded data types:

fst and snd, functions to extract the content of a pair
swap, a function that exchanges the content of a pair
curry, a function to turn functions of pairs into functions of two arguments
uncurry, a function to turn functions of two arguments into functions of pairs
isJust and isNothing, predicates testing wether a Maybe contains data
isLeft and isRight, predicates testing which side is contained in an Either
cons, a function to prepend an element to a list
concat, a function to contanetate two lists
catMaybes, a function to flatten a list of Maybes by removing Nothings
null, a predicate testing wether a list is empty
length, a function returning the number of elements in a list
map, a function to transform the contents of a list according to a given function
zip, a funtion to merge two lists into a list of pairs
partition, a function that splits a list of Eithers in a pair of Lefts and Rights
foldl and foldr, functions to reduce a list to a single value by successive application of a given function
take, a function to limit a list to a number of initial elements

Boilerplate code:
```haskell
{-# LANGUAGE ScopedTypeVariables, Rank2Types #-}
module ScottEncoding where

import Prelude hiding (null, length, map, foldl, foldr, take, fst, snd, curry, uncurry, concat, zip, (++))

newtype SMaybe a = SMaybe { runMaybe :: forall b. b -> (a -> b) -> b }
newtype SList a = SList { runList :: forall b. b -> (a -> SList a -> b) -> b }
newtype SEither a b = SEither { runEither :: forall c. (a -> c) -> (b -> c) -> c }
newtype SPair a b = SPair { runPair :: forall c. (a -> b -> c) -> c }

toPair :: SPair a b -> (a,b)
toPair = error "toPair"
fromPair :: (a,b) -> SPair a b
fromPair = error "fromPair"
fst :: SPair a b -> a
fst = error "fst"
snd :: SPair a b -> b
snd = error "snd"
swap :: SPair a b -> SPair b a
swap = error "swap"
curry :: (SPair a b -> c) -> (a -> b -> c)
curry = error "curry"
uncurry :: (a -> b -> c) -> (SPair a b -> c)
uncurry = error "uncurry"

toMaybe :: SMaybe a -> Maybe a
toMaybe = error "toMaybe"
fromMaybe :: Maybe a -> SMaybe a
fromMaybe = error "fromMaybe"
isJust :: SMaybe a -> Bool
isJust = error "isJust"
isNothing :: SMaybe a -> Bool
isNothing = error "isNothing"
catMaybes :: SList (SMaybe a) -> SList a
catMaybes = error "catMaybes"

toEither :: SEither a b -> Either a b
toEither = error "toEither"
fromEither :: Either a b -> SEither a b
fromEither = error "fromEither"
isLeft :: SEither a b -> Bool
isLeft = error "isLeft"
isRight :: SEither a b -> Bool
isRight = error "isRight"
partition :: SList (SEither a b) -> SPair (SList a) (SList b)
partition = error "partition"

toList :: SList a -> [a]
toList = error "toList"
fromList :: [a] -> SList a
fromList = error "fromList"
cons :: a -> SList a -> SList a
cons = error "cons"
concat :: SList a -> SList a -> SList a
concat = error "concat"
null :: SList a -> Bool
null = error "null"
length :: SList a -> Int
length = error "length"
map :: (a -> b) -> SList a -> SList b
map = error "map"
zip :: SList a -> SList b -> SList (SPair a b)
zip = error "zip"
foldl :: (b -> a -> b) -> b -> SList a -> b
foldl = error "foldl"
foldr :: (a -> b -> b) -> b -> SList a -> b
foldr = error "foldr"
take :: Int -> SList a -> SList a
take = error "take"
```