diff --git a/tp9/merge_sort.py b/tp9/merge_sort.py
new file mode 100644
index 0000000000000000000000000000000000000000..4da108338ae8f5e192c33db3e0d0043eac3533f5
--- /dev/null
+++ b/tp9/merge_sort.py
@@ -0,0 +1,197 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+
+"""
+:mod:`recursive sorts`
+:author: `FIL - FST - Univ. Lille.fr <http://portail.fil.univ-lille1.fr>`_
+:date: 2016, september. Last revised: 2018, september
+
+Some recursive sorting algorithms:
+
+- quicksort
+- mergesort
+
+"""
+from typing import Callable, TypeVar
+from aplst import ApLst
+
+
+T = TypeVar('T')
+
+
+def compare(a: T, b: T) -> int:
+    """
+    return:
+       - -1 if a < b
+       -  1 if a > b
+       -  0 if a = b
+    precondition: a and b must be comparable with <
+    exemples:
+
+    $$$ compare(0, 1)
+    -1
+    $$$ compare('a', 'a')
+    0
+    $$$ compare((2, 1), (1, 2))
+    1
+    """
+    if a < b:
+        return -1
+    elif a > b:
+        return 1
+    else:
+        return 0
+
+
+def length(li: ApLst) -> int:
+    """
+    return the length of li.
+
+    precondition: none
+
+    examples:
+
+    $$$ length(ApLst())
+    0
+    $$$ length(ApLst(3, ApLst(1, ApLst(4, ApLst()))))
+    3
+    """
+    leng = 0
+    while not li.is_empty():
+            li = li.tail()
+            leng += 1
+    return leng
+        
+
+
+def native_to_list(li: list[T]) -> ApLst:
+    """
+    return a recursive list containing the same element of li.
+
+    precondition: none
+
+    examples:
+
+    $$$ native_to_list([]).is_empty()
+    True
+    $$$ rec_lst = native_to_list([3, 1, 4, 1, 5])
+    $$$ length(rec_lst)
+    5
+    $$$ rec_lst.head()
+    3
+    $$$ l = rec_lst.tail()
+    $$$ l.head()
+    1
+    $$$ l = l.tail()
+    $$$ l.head()
+    4
+    """
+    l = ApLst()
+    for i in range(1, len(li)+1):
+        l = ApLst(li[-i], l)
+    return l
+    
+
+def list_to_native(li: ApLst) -> list[T]:
+    """
+    return a native python list containing the same element of li.
+
+    precondition: none
+
+    examples:
+
+    $$$ list_to_native(ApLst())
+    []
+    $$$ list_to_native(ApLst(3, ApLst(1, ApLst(4, ApLst(1, ApLst(5, ApLst()))))))
+    [3, 1, 4, 1, 5]
+    """
+    l = []
+    while not li.is_empty():
+        l.append(li.head())
+        li = li.tail()
+    return l
+        
+
+def is_sorted(l: ApLst, comp: Callable[[T, T], int]=compare) -> bool:
+    """
+    return True if list l is sorted by ascending order
+    and False otherwise.
+
+    precondition: elements of l must be comparable
+    exemples:
+
+    $$$ is_sorted(native_to_list([1, 2, 3, 4]))
+    True
+    $$$ is_sorted(native_to_list([1, 2, 4, 3]))
+    False
+    """
+    res = True
+    for i in range(length(l)-1):
+        a = l.head()
+        l = l.tail()
+        if a > l.head():
+            res = False
+    return res
+
+
+def split(l: ApLst) -> tuple[ApLst, ApLst]:
+    """
+    return a couple (l1,l2) of lists of equal length
+
+    exemples:
+
+    $$$ l = [3, 1, 4, 1, 5, 9, 2]
+    $$$ l1, l2 = split(native_to_list(l))
+    $$$ abs(length(l1) - length(l2)) <= 1
+    True
+    $$$ l3 = list_to_native(l1) + list_to_native(l2)
+    $$$ len(l3) == len(l)
+    True
+    $$$ all(k in l for k in l3)
+    True
+    """
+    
+
+
+def merge(l1: ApLst, l2: ApLst,
+          comp: Callable[[T, T], int]=compare) -> ApLst:
+    """
+    return a list containing all elements de l1 and l2.
+    If l1 and l2 are sorted, so is the returned list.
+
+    precondition: elements of l1 and l2 are comparable
+    exemples:
+
+    $$$ list_to_native(merge(native_to_list([1, 3, 4, 9]), native_to_list([1, 2, 5])))
+    [1, 1, 2, 3, 4, 5, 9]
+    """
+    ...
+
+
+def mergesort(l: ApLst, comp: Callable[[T, T], int]=compare) -> ApLst:
+    """
+    return a new list containing elements of l sorted by ascending order.
+
+    precondition: elements of l are comparable
+    exemples:
+
+    $$$ list_to_native(mergesort(native_to_list([3, 1, 4, 1, 5, 9, 2])))
+    [1, 1, 2, 3, 4, 5, 9]
+    $$$ import random
+    $$$ n = random.randrange(20)
+    $$$ l = native_to_list([random.randrange(20) for k in range(n)])
+    $$$ l1 = mergesort(l)
+    $$$ length(l1) == length(l)
+    True
+    $$$ is_sorted(l1)
+    True
+    """
+    ...
+
+
+if (__name__ == '__main__'):
+    import apl1test
+    apl1test.testmod("merge_sort.py")
+
+
+