diff --git a/lambda-calculator.cabal b/lambda-calculator.cabal
--- a/lambda-calculator.cabal
+++ b/lambda-calculator.cabal
@@ -1,5 +1,5 @@
 name:                lambda-calculator
-version:             0.5.0
+version:             1.0.0
 synopsis:            A lambda calculus interpreter
 description:         Please see README.md
 homepage:            https://github.com/sgillespie/lambda-calculus#readme
diff --git a/src/Language/Lambda/Eval.hs b/src/Language/Lambda/Eval.hs
--- a/src/Language/Lambda/Eval.hs
+++ b/src/Language/Lambda/Eval.hs
@@ -25,6 +25,19 @@
   where uniq = fromMaybe name (find (`notElem` freeVars) uniqs)
 alphaConvert _ _ e = e
 
+etaConvert :: Eq n => LambdaExpr n -> LambdaExpr n
+etaConvert (Abs n (App e1 (Var n')))
+  | n == n'   = etaConvert e1
+  | otherwise = Abs n (App (etaConvert e1) (Var n'))
+etaConvert (Abs n e@(Abs _ _)) 
+  -- If `etaConvert e == e` then etaConverting it will create an infinite loop
+  | e == e'   = Abs n e'
+  | otherwise = etaConvert (Abs n e')
+  where e' = etaConvert e
+etaConvert (Abs n expr) = Abs n (etaConvert expr)
+etaConvert (App e1 e2)  = App (etaConvert e1) (etaConvert e2)
+etaConvert expr@(Var _) = expr
+
 sub :: Eq n => n -> LambdaExpr n -> LambdaExpr n -> LambdaExpr n
 sub name b@(Var name') expr
   | name == name' = expr
diff --git a/test/Language/Lambda/EvalSpec.hs b/test/Language/Lambda/EvalSpec.hs
--- a/test/Language/Lambda/EvalSpec.hs
+++ b/test/Language/Lambda/EvalSpec.hs
@@ -74,6 +74,28 @@
           uniques = ["x", "y"]
       alphaConvert uniques freeVars expr `shouldBe` Abs "y" (Var "y")
 
+  describe "etaConvert" $ do
+    it "eta converts simple expressions" $ do
+      let expr = Abs "x" $ App (Var "f") (Var "x")
+      etaConvert expr `shouldBe` Var "f" 
+
+    it "eta converts nested applications" $ do
+      let expr = Abs "y" $ App (App (Var "f") (Var "x")) (Var "y")
+      etaConvert expr `shouldBe` App (Var "f") (Var "x")
+
+      let expr' = Abs "x" $ Abs "y" (App (App (Var "f") (Var "x")) (Var "y"))
+      etaConvert expr' `shouldBe` Var "f" 
+
+      let expr'' = Abs "x" (Abs "y" (App (Var "y") (Var "x")))
+      etaConvert expr'' `shouldBe` expr''
+
+      let expr''' = Abs "f" (Abs "x" (Var "x"))
+      etaConvert expr''' `shouldBe` expr'''
+
+    it "ignores non-eta convertable expressions" $ do
+      let expr = Abs "x" $ Var "x"
+      etaConvert expr `shouldBe` expr
+
   describe "freeVarsOf" $ do
     it "Returns simple vars" $ do
       freeVarsOf (Var "x") `shouldBe` ["x"]
