¿Qué tipos de clases deben definirse para una ruta Yesod?

En mi aplicación, mi modelo de datos tiene varias instancias diferentes de usar un entero o una cadena para algún identificador. Por razones de seguridad, seguí adelante y envolví esos identificadores en nuevas declaraciones de tipo:

newtype DocId = DocId Integer
newtype GroupName = GroupName String
newtype UserName = UserName String

Cuando configuro mis rutas Yesod, descubro que tengo que crear al menos tres instancias para cada una de ellas, y las instancias son casi siempre idénticas

instance Read DocId where
    readsPrec prec val = case reads val of
        (i, ""):_ -> [(DocId i, "")]
        [] -> []

instance B.ToMarkup DocId where
    toMarkup (DocId val) = B.toMarkup val

instance PathPiece DocId where
    toPathPiece (DocId i) = T.pack $ show i
    fromPathPiece s =
        case reads $ T.unpack s of
            (i, ""):_ -> Just i
            [] -> Nothing

Este texto, una y otra vez.

¿Qué necesito configurar realmente para procesar mi tipo de datos en las URL (como @ {ViewDocument docId}) y poder analizar esas URL?

Respuestas a la pregunta(2)

Su respuesta a la pregunta