2011-06-07 15 views
13

Revisé el libro de Yesod y la fuente y aprendí prácticamente cómo funciona todo. Pero antes de escribir mis propias cosas, hay una cosa en el sitio de scaffolded que simplemente no entiendo.No entiendo lo que este tipo de cosas familiares en yesod es para

Así que Andamios un sitio "copywww" y en las CopyWWWState.hs del archivo está el código:

instance YesodPersist CopyWWWState where 
    type YesodDB CopyWWWState = SqlPersist 
    runDB db = liftIOHandler 
      $ fmap connPool getYesod >>= Settings.runConnectionPool db 

instance YesodAuth CopyWWWState where 
    type AuthId CopyWWWState = UserId 

    -- Where to send a user after successful login 
    loginDest _ = RootR 
    -- Where to send a user after logout 
    logoutDest _ = RootR 

    getAuthId creds = runDB $ do 
     x <- getBy $ UniqueUser $ credsIdent creds 
     case x of 
      Just (uid, _) -> return $ Just uid 
      Nothing -> do 
       fmap Just $ insert $ User (credsIdent creds) Nothing 

    authPlugins = [ authOpenId 
        , authEmail 
        ] 

Las líneas que no entiendo son los que:

type AuthId CopyWWWState = UserId 
type YesodDB CopyWWWState = SqlPersist 

Cuando los elimino, obviamente recibo errores, pero no estoy seguro de por qué son necesarios en primer lugar. Cuando busco en la fuente "UserId" o "SqlPersist", no encuentro nada que parezca prometedor. ¿Para qué necesita este código exactamente? ¿Qué beneficio obtiene yesod del uso de familias de tipos en estas clases?

Respuesta

7

Está sucediendo algo en el andamio que podría no ser inmediatamente obvio. En el config/modelo, existe una entidad persistente define algo como:

User 
    name String 
    foo String 

Esto creará un tipo de usuario que es una instancia de PersistEntity y un tipo UserId que se utiliza como tal:

instance PersistEntity User where 
    ... 
    Key User = UserId 

la razón de que el andamio pone en:

type AuthId CopyWWWState = UserId 

es sólo que el usuario es un punto de referencia lógico. Ahora, en su código, cada vez que llame al requireAuth obtendrá algo como Handler User y requireAuthId le dará un Handler UserId que es equivalente a Handler (Key User). Puede cambiarlos a cualquier cosa que desee, pero deberá cambiar algunas de las otras funciones en la instancia de clase de tipo YesodAuth.

Espero que esto ayude. Yesod rocas. toma una semana o dos para tener la sensación de cómo se mantiene unido, pero cuando haces cosas como esta son bastante poderosas.

2

Las familias de tipos son similares a las dependencias funcionales. Ambas proporcionan una forma de abstraer una clase de tipo en más de un parámetro mientras mantienen feliz el contador de tipos. El type local solo significa que tiene un parámetro adicional vinculado por la instancia. Esto significa que la instancia puede decidir por sí misma qué tipo usar en ese lugar. Una instancia también puede usar un tipo más general en lugar de un específico para dar al usuario la opción. En su caso, posiblemente confíe en el hecho de que la base de datos ypur tipo YesodDB es de hecho una base de datos SQL (SqlPersist). Entonces esta información es necesaria para satisfacer el typechecker.

Cuestiones relacionadas