diff --git a/ditto.cabal b/ditto.cabal
--- a/ditto.cabal
+++ b/ditto.cabal
@@ -1,5 +1,5 @@
 Name:          ditto
-Version:       0.2
+Version:       0.3
 Synopsis:      ditto is a type-safe HTML form generation and validation library
 Description:   ditto follows in the footsteps of formlets and
                digestive-functors <= 0.2. It provides a
diff --git a/src/Ditto/Backend.hs b/src/Ditto/Backend.hs
--- a/src/Ditto/Backend.hs
+++ b/src/Ditto/Backend.hs
@@ -1,6 +1,7 @@
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE FunctionalDependencies #-}
 
 {- |
 This module contains two classes. 'FormInput' is a class which is parameterized over the @input@ type used to represent form data in different web frameworks. There should be one instance for each framework, such as Happstack, Snap, WAI, etc.
@@ -55,12 +56,10 @@
   MissingDefaultValue -> "Missing default value."
 
 -- | A Class to lift a 'CommonFormError' into an application-specific error type
-class FormError e where
-  type ErrorInputType e
-  commonFormError :: (CommonFormError (ErrorInputType e)) -> e
+class FormError err input | err -> input where
+  commonFormError :: CommonFormError input -> err
 
-instance FormError Text where
-  type ErrorInputType Text = Text
+instance FormError Text Text where
   commonFormError = commonFormErrorText id
 
 -- | Class which all backends should implement.
@@ -74,7 +73,7 @@
   -- | Parse the input into a string. This is used for simple text fields
   -- among other things
   --
-  getInputString :: (FormError error, ErrorInputType error ~ input) => input -> Either error String
+  getInputString :: (FormError error input) => input -> Either error String
   getInputString input =
     case getInputStrings input of
       [] -> Left (commonFormError $ NoStringFound input)
@@ -87,7 +86,7 @@
 
   -- | Parse the input value into 'Text'
   --
-  getInputText :: (FormError error, ErrorInputType error ~ input) => input -> Either error Text
+  getInputText :: (FormError error input) => input -> Either error Text
   getInputText input =
     case getInputTexts input of
       [] -> Left (commonFormError $ NoStringFound input)
@@ -101,4 +100,4 @@
 
   -- | Get a file descriptor for an uploaded file
   --
-  getInputFile :: (FormError error, ErrorInputType error ~ input) => input -> Either error (FileType input)
+  getInputFile :: (FormError error input) => input -> Either error (FileType input)
diff --git a/src/Ditto/Generalized.hs b/src/Ditto/Generalized.hs
--- a/src/Ditto/Generalized.hs
+++ b/src/Ditto/Generalized.hs
@@ -11,12 +11,12 @@
 import qualified Ditto.Generalized.Internal as G
 
 -- | used for constructing elements like @\<input type=\"text\"\>@, which pure a single input value.
-input :: (Monad m, FormError err) => (input -> Either err a) -> (FormId -> a -> view) -> a -> Form m input err view a
+input :: (Monad m, FormError err input) => (input -> Either err a) -> (FormId -> a -> view) -> a -> Form m input err view a
 input = G.input getFormId
 
 -- | used for elements like @\<input type=\"submit\"\>@ which are not always present in the form submission data.
 inputMaybe
-  :: (Monad m, FormError err)
+  :: (Monad m, FormError err input)
   => (input -> Either err a)
   -> (FormId -> Maybe a -> view)
   -> Maybe a
@@ -25,7 +25,7 @@
 
 -- | used to construct elements with optional initial values, which are still required
 inputMaybeReq
-  :: (Monad m, FormError err)
+  :: (Monad m, FormError err input)
   => (input -> Either err a)
   -> (FormId -> Maybe a -> view)
   -> Maybe a
@@ -41,14 +41,14 @@
 
 -- | used for @\<input type=\"file\"\>@
 inputFile
-  :: forall m input err view. (Monad m, FormInput input, FormError err, ErrorInputType err ~ input)
+  :: forall m input err view. (Monad m, FormInput input, FormError err input)
   => (FormId -> view)
   -> Form m input err view (FileType input)
 inputFile = G.inputFile getFormId
 
 -- | used for groups of checkboxes, @\<select multiple=\"multiple\"\>@ boxes
 inputMulti
-  :: forall m input err view a lbl. (FormError err, ErrorInputType err ~ input, FormInput input, Monad m)
+  :: forall m input err view a lbl. (FormError err input, FormInput input, Monad m)
   => [(a, lbl)] -- ^ value, label, initially checked
   -> (FormId -> [(FormId, Int, lbl, Bool)] -> view) -- ^ function which generates the view
   -> (a -> Bool) -- ^ isChecked/isSelected initially
@@ -57,7 +57,7 @@
 
 -- | radio buttons, single @\<select\>@ boxes
 inputChoice
-  :: forall a m err input lbl view. (FormError err, ErrorInputType err ~ input, FormInput input, Monad m)
+  :: forall a m err input lbl view. (FormError err input, FormInput input, Monad m)
   => (a -> Bool) -- ^ is default
   -> [(a, lbl)] -- ^ value, label
   -> (FormId -> [(FormId, Int, lbl, Bool)] -> view) -- ^ function which generates the view
@@ -66,7 +66,7 @@
 
 -- | radio buttons, single @\<select\>@ boxes
 inputChoiceForms
-  :: forall a m err input lbl view. (Monad m, FormError err, ErrorInputType err ~ input, FormInput input)
+  :: forall a m err input lbl view. (Monad m, FormError err input, FormInput input)
   => a
   -> [(Form m input err view a, lbl)] -- ^ value, label
   -> (FormId -> [(FormId, Int, FormId, view, lbl, Bool)] -> view) -- ^ function which generates the view
diff --git a/src/Ditto/Generalized/Internal.hs b/src/Ditto/Generalized/Internal.hs
--- a/src/Ditto/Generalized/Internal.hs
+++ b/src/Ditto/Generalized/Internal.hs
@@ -1,6 +1,6 @@
-{-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE DoAndIfThenElse #-}
+{-# LANGUAGE ScopedTypeVariables #-}
 
 -- This module provides helper functions for HTML input elements. These helper functions are not specific to any particular web framework or html library.
 
@@ -18,7 +18,7 @@
 
 -- | used for constructing elements like @\<input type=\"text\"\>@, which pure a single input value.
 input
-  :: (Monad m, FormError err)
+  :: (Monad m, FormError err input)
   => FormState m input FormId
   -> (input -> Either err a)
   -> (FormId -> a -> view)
@@ -61,7 +61,7 @@
         )
 
 inputMaybeReq
-  :: (Monad m, FormError err)
+  :: (Monad m, FormError err input)
   => FormState m input FormId
   -> (input -> Either err a)
   -> (FormId -> Maybe a -> view)
@@ -107,7 +107,7 @@
 
 -- | used for elements like @\<input type=\"submit\"\>@ which are not always present in the form submission data.
 inputMaybe
-  :: (Monad m, FormError err)
+  :: (Monad m, FormError err input)
   => FormState m input FormId
   -> (input -> Either err a)
   -> (FormId -> Maybe a -> view)
@@ -176,7 +176,7 @@
 
 -- | used for @\<input type=\"file\"\>@
 inputFile
-  :: forall m input err view. (Monad m, FormInput input, FormError err, ErrorInputType err ~ input)
+  :: forall m input err view. (Monad m, FormInput input, FormError err input)
   => FormState m input FormId
   -> (FormId -> view)
   -> Form m input err view (FileType input)
@@ -212,12 +212,12 @@
           )
   where
     -- just here for the type-signature to make the type-checker happy
-    getInputFile' :: (FormError err, ErrorInputType err ~ input) => input -> Either err (FileType input)
+    getInputFile' :: (FormError err input) => input -> Either err (FileType input)
     getInputFile' = getInputFile
 
 -- | used for groups of checkboxes, @\<select multiple=\"multiple\"\>@ boxes
 inputMulti
-  :: forall m input err view a lbl. (FormError err, ErrorInputType err ~ input, FormInput input, Monad m)
+  :: forall m input err view a lbl. (FormError err input, FormInput input, Monad m)
   => FormState m input FormId
   -> [(a, lbl)] -- ^ value, label, initially checked
   -> (FormId -> [(FormId, Int, lbl, Bool)] -> view) -- ^ function which generates the view
@@ -274,7 +274,7 @@
 
 -- | radio buttons, single @\<select\>@ boxes
 inputChoice
-  :: forall a m err input lbl view. (FormError err, ErrorInputType err ~ input, FormInput input, Monad m)
+  :: forall a m err input lbl view. (FormError err input, FormInput input, Monad m)
   => FormState m input FormId
   -> (a -> Bool) -- ^ is default
   -> [(a, lbl)] -- ^ value, label
@@ -349,7 +349,7 @@
 
 -- | radio buttons, single @\<select\>@ boxes
 inputChoiceForms
-  :: forall a m err input lbl view. (Monad m, FormError err, ErrorInputType err ~ input, FormInput input)
+  :: forall a m err input lbl view. (Monad m, FormError err input, FormInput input)
   => FormState m input FormId
   -> a
   -> [(Form m input err view a, lbl)] -- ^ value, label
diff --git a/src/Ditto/Generalized/Named.hs b/src/Ditto/Generalized/Named.hs
--- a/src/Ditto/Generalized/Named.hs
+++ b/src/Ditto/Generalized/Named.hs
@@ -12,13 +12,13 @@
 import qualified Ditto.Generalized.Internal as G
 
 -- | used for constructing elements like @\<input type=\"text\"\>@, which pure a single input value.
-input :: (Monad m, FormError err) => String -> (input -> Either err a) -> (FormId -> a -> view) -> a -> Form m input err view a
+input :: (Monad m, FormError err input) => String -> (input -> Either err a) -> (FormId -> a -> view) -> a -> Form m input err view a
 input name = G.input (getNamedFormId name)
 
 
 -- | used to construct elements with optional initial values, which are still required
 inputMaybeReq
-  :: (Monad m, FormError err)
+  :: (Monad m, FormError err input)
   => String
   -> (input -> Either err a)
   -> (FormId -> Maybe a -> view)
@@ -28,7 +28,7 @@
 
 -- | used for elements like @\<input type=\"submit\"\>@ which are not always present in the form submission data.
 inputMaybe
-  :: (Monad m, FormError err)
+  :: (Monad m, FormError err input)
   => String
   -> (input -> Either err a)
   -> (FormId -> Maybe a -> view)
@@ -46,7 +46,7 @@
 
 -- | used for @\<input type=\"file\"\>@
 inputFile
-  :: forall m input err view. (Monad m, FormInput input, FormError err, ErrorInputType err ~ input)
+  :: forall m input err view. (Monad m, FormInput input, FormError err input)
   => String
   -> (FormId -> view)
   -> Form m input err view (FileType input)
@@ -54,7 +54,7 @@
 
 -- | used for groups of checkboxes, @\<select multiple=\"multiple\"\>@ boxes
 inputMulti
-  :: forall m input err view a lbl. (FormError err, ErrorInputType err ~ input, FormInput input, Monad m)
+  :: forall m input err view a lbl. (FormError err input, FormInput input, Monad m)
   => String
   -> [(a, lbl)] -- ^ value, label, initially checked
   -> (FormId -> [(FormId, Int, lbl, Bool)] -> view) -- ^ function which generates the view
@@ -64,7 +64,7 @@
 
 -- | radio buttons, single @\<select\>@ boxes
 inputChoice
-  :: forall a m err input lbl view. (FormError err, ErrorInputType err ~ input, FormInput input, Monad m)
+  :: forall a m err input lbl view. (FormError err input, FormInput input, Monad m)
   => String
   -> (a -> Bool) -- ^ is default
   -> [(a, lbl)] -- ^ value, label
@@ -74,7 +74,7 @@
 
 -- | radio buttons, single @\<select\>@ boxes
 inputChoiceForms
-  :: forall a m err input lbl view. (Monad m, FormError err, ErrorInputType err ~ input, FormInput input)
+  :: forall a m err input lbl view. (Monad m, FormError err input, FormInput input)
   => String
   -> a
   -> [(Form m input err view a, lbl)] -- ^ value, label
