superposición superposicion samsung para pantalla desactivar aplicacion haskell haskelldb

haskell - superposicion - superposición de pantalla samsung j7



¿Cómo puedo usar HaskellDB con campos polimórficos?(Problemas con la superposición de instancias) (1)

Tengo un esquema que tiene 6 tipos diferentes de entidades, pero todas tienen muchas cosas en común. Pensé que probablemente podría abstraer mucho de esta similitud en el nivel de tipo, pero me he topado con un problema con HaskellDB y las instancias superpuestas. Aquí está el código con el que comencé, que funciona bien:

import Database.HaskellDB import Database.HaskellDB.DBLayout data Revision a = Revision deriving Eq data Book = Book instance FieldTag (Revision a) where fieldName _ = "rev_id" revIdField :: Attr (Revision Book) (Revision Book) revIdField = mkAttr undefined branch :: Table (RecCons (Revision Book) (Expr (Revision Book)) RecNil) branch = baseTable "branch" $ hdbMakeEntry undefined bookRevision :: Table (RecCons (Revision Book) (Expr (Revision Book)) RecNil) bookRevision = baseTable "book_revision" $ hdbMakeEntry undefined masterHead :: Query (Rel (RecCons (Revision Book) (Expr (Revision Book)) RecNil)) masterHead = do revisions <- table bookRevision branches <- table branch restrict $ revisions ! revIdField .==. branches ! revIdField return revisions

Esto funciona bien, pero la branch es demasiado específica. Lo que realmente quiero expresar es lo siguiente:

branch :: Table (RecCons (Revision entity) (Expr (Revision entity)) RecNil) branch = baseTable "branch" $ hdbMakeEntry undefined

Sin embargo, con este cambio, aparece el siguiente error:

Overlapping instances for HasField (Revision Book) (RecCons (Revision entity0) (Expr (Revision entity0)) RecNil) arising from a use of `!'' Matching instances: instance [overlap ok] HasField f r => HasField f (RecCons g a r) -- Defined in Database.HaskellDB.HDBRec instance [overlap ok] HasField f (RecCons f a r) -- Defined in Database.HaskellDB.HDBRec (The choice depends on the instantiation of `entity0'' To pick the first instance above, use -XIncoherentInstances when compiling the other instance declarations) In the second argument of `(.==.)'', namely `branches ! revIdField'' In the second argument of `($)'', namely `revisions ! revIdField .==. branches ! revIdField'' In a stmt of a ''do'' expression: restrict $ revisions ! revIdField .==. branches ! revIdField

Intenté lanzar ciegamente -XOverlappingInstances y -XIncoherentInstances en esto, pero eso no ayuda (y me gustaría entender realmente por qué el reemplazo de un tipo concreto con una variable de tipo hace que esto sea tan problemático).

¡Cualquier ayuda y consejo sería muy apreciado!


Con la edad de esta pregunta, es probable que sea demasiado tarde una respuesta para hacer una diferencia para ti, pero tal vez si otra persona viene con un problema similar ...

Todo se reduce al hecho de que no se puede inferir que desee que la entity consulte el Book cuando se usa la masterHead en masterHead . La parte del mensaje de error que dice

La elección depende de la instanciación de `entity0 ''

le dice dónde necesita eliminar la ambigüedad, específicamente que necesita dar más información sobre qué entity0 debería ser. Puede dar algunas anotaciones de tipo para ayudar.

Primero, defina la branch como

type BranchTable entity = Table (RecCons (Revision entity) (Expr (Revision entity)) RecNil) branch :: BrancTable entity branch = baseTable "branch" $ hdbMakeEntry undefined

y luego cambiar masterHead para leer

masterHead :: Query (Rel (RecCons (Revision Book) (Expr (Revision Book)) RecNil)) masterHead = do revisions <- table bookRevision branches <- table (branch :: BranchTable Book) restrict $ revisions ! revIdField .==. branches ! revIdField return revisions

Tenga en cuenta la anotación de tipo aplicada a branch : branch :: BranchTable Book que sirve para eliminar la ambigüedad que causaba el error de tipo.

Para hacer que masterHead aplique a cualquier cosa que tenga un campo de Revision e , puede usar esta definición:

masterHead :: (ShowRecRow r, HasField (Revision e) r) => Table r -> e -> Query (Rel r) masterHead revTable et = do revisions <- table revTable branches <- table branch'' restrict $ revisions ! revIdField'' .==. branches ! revIdField'' return revisions where (branch'', revIdField'') = revBundle revTable et revBundle :: HasField (Revision e) r => Table r -> e -> (BranchTable e, Attr (Revision e) (Revision e)) revBundle table et = (branch, revIdField)

El argumento et se necesita para especificar qué tipo de e debe ser y puede ser undefined atribuido al tipo correcto como en

masterHead bookRevision (undefined :: Book)

que genera el SQL

SELECT rev_id1 as rev_id FROM (SELECT rev_id as rev_id2 FROM branch as T1) as T1, (SELECT rev_id as rev_id1 FROM book_revision as T1) as T2 WHERE rev_id1 = rev_id2

sin embargo, esto requiere FlexibleContexts , pero se puede aplicar al módulo de asker sin recompilar HaskellDB.