<NME> test_state.py
<BEF> import unittest

from typing import Callable
from oslash import State
from oslash.util import identity, compose

# pure = State.pure
unit = State.unit
put = State.put


class TestState(unittest.TestCase):
    def test_state_greeter(self):

        def greeter() -> State:
            state = get().bind(lambda name:
        def greeter() -> State:
                                   lambda _: unit("hello, %s!" % name)))
            return state

        result = greeter().run()("adit")
        self.assertEqual("hello, adit!", result[0])
        self.assertEqual("tintin", result[1])


class TestStateFunctor(unittest.TestCase):

    def test_state_functor_map(self):
        x = unit(42)
        f = lambda x: x * 10

        f = lambda x: x * 10

            unit(420)
        )

    def test_state_functor_law_1(self):
        # fmap id = id
        x = unit(42)

        x = unit(42)

            x
        )

    def test_state_functor_law2(self):
        # fmap (f . g) x = fmap f (fmap g x)
        def f(x):
            return x+10

        def g(x):
            return x*10

        x = unit(42)

        x : State[int, int] = unit(42)

        self.assertEqual(
            x.map(compose(f, g)).run(state),
            x.map(g).map(f).run(state)

class TestStateMonad(unittest.TestCase):

    def test_state_monad_bind(self):
        m = unit(42)
        f = lambda x: unit(x*10)

        self.assertEqual(
            m.bind(f),
            unit(420)
        )

    def test_state_monad_law_left_identity(self):
        # return x >>= f is the same thing as f x

        f = lambda x: unit(x+100000)
        x = 3

        self.assertEqual(

            f(x)
        )

    def test_state_monad_law_right_identity(self):
        # m >>= return is no different than just m.

        m = unit("move on up")

        m = unit("move on up")

            m
        )

    def test_state_monad_law_associativity(self):
        # (m >>= f) >>= g is just like doing m >>= (\x -> f x >>= g)
        m = unit(42)
        f = lambda x: unit(x+1000)
        g = lambda y: unit(y*42)

        self.assertEqual(
            m.bind(f).bind(g),
        self.assertEqual(
            m.bind(f).bind(g).run(state),
            m.bind(lambda x: f(x).bind(g)).run(state)
        )

<MSG> Refactored with type hinting using generics. Added pure print/input for ioactions.

<DFF> @@ -10,7 +10,8 @@ get = State.get
 
 
 class TestState(unittest.TestCase):
-    def test_state_greeter(self):
+
+    def test_state_greeter(self) -> None:
 
         def greeter() -> State:
             state = get().bind(lambda name:
@@ -18,14 +19,14 @@ class TestState(unittest.TestCase):
                                    lambda _: unit("hello, %s!" % name)))
             return state
 
-        result = greeter().run()("adit")
+        result = greeter().run("adit")
         self.assertEqual("hello, adit!", result[0])
         self.assertEqual("tintin", result[1])
 
 
 class TestStateFunctor(unittest.TestCase):
 
-    def test_state_functor_map(self):
+    def test_state_functor_map(self) -> None:
         x = unit(42)
         f = lambda x: x * 10
 
@@ -34,7 +35,7 @@ class TestStateFunctor(unittest.TestCase):
             unit(420)
         )
 
-    def test_state_functor_law_1(self):
+    def test_state_functor_law_1(self) -> None:
         # fmap id = id
         x = unit(42)
 
@@ -43,13 +44,13 @@ class TestStateFunctor(unittest.TestCase):
             x
         )
 
-    def test_state_functor_law2(self):
+    def test_state_functor_law2(self) -> None:
         # fmap (f . g) x = fmap f (fmap g x)
         def f(x):
-            return x+10
+            return x + 10
 
         def g(x):
-            return x*10
+            return x * 10
 
         x = unit(42)
 
@@ -61,19 +62,19 @@ class TestStateFunctor(unittest.TestCase):
 
 class TestStateMonad(unittest.TestCase):
 
-    def test_state_monad_bind(self):
+    def test_state_monad_bind(self) -> None:
         m = unit(42)
-        f = lambda x: unit(x*10)
+        f = lambda x: unit(x * 10)
 
         self.assertEqual(
             m.bind(f),
             unit(420)
         )
 
-    def test_state_monad_law_left_identity(self):
+    def test_state_monad_law_left_identity(self) -> None:
         # return x >>= f is the same thing as f x
 
-        f = lambda x: unit(x+100000)
+        f = lambda x: unit(x + 100000)
         x = 3
 
         self.assertEqual(
@@ -81,7 +82,7 @@ class TestStateMonad(unittest.TestCase):
             f(x)
         )
 
-    def test_state_monad_law_right_identity(self):
+    def test_state_monad_law_right_identity(self) -> None:
         # m >>= return is no different than just m.
 
         m = unit("move on up")
@@ -91,11 +92,11 @@ class TestStateMonad(unittest.TestCase):
             m
         )
 
-    def test_state_monad_law_associativity(self):
+    def test_state_monad_law_associativity(self) -> None:
         # (m >>= f) >>= g is just like doing m >>= (\x -> f x >>= g)
         m = unit(42)
-        f = lambda x: unit(x+1000)
-        g = lambda y: unit(y*42)
+        f = lambda x: unit(x + 1000)
+        g = lambda y: unit(y * 42)
 
         self.assertEqual(
             m.bind(f).bind(g),

Refactored with type hinting using generics. Added pure print/input for ioactions.