2014-09-17 9 views
5

sto cercando di definire un Newtype Markdown, e l'utilizzo di GeneralizedNewtypeDeriving per definire automaticamente nuove istanze:GeneralizedNewtypeDeriving non riesce per PersistFieldSql

import Text.Markdown 
import Yesod.Text.Markdown 
import Database.Persist.Sql 

newtype MarkdownNewT = MarkdownNewT { getMarkdown :: Markdown } 
    deriving (Eq, IsString, Monoid, PersistField, PersistFieldSql) 

Questo non riesce per la PersistFieldSql con il seguente messaggio:

Could not coerce from ‘m Markdown’ to ‘m MarkdownNewT’ 
    because ‘m Markdown’ and ‘m MarkdownNewT’ are different types. 
    arising from the coercion of the method ‘sqlType’ from type 
       ‘forall (m :: * -> *). Monad m => m Markdown -> SqlType’ to type 
       ‘forall (m :: * -> *). Monad m => m MarkdownNewT -> SqlType’ 

Ciò è dovuto alle nuove funzionalità roles di GHC 7.8.2? In quel caso particolare non so cosa fare, dal momento che Markdown è di per sé un nuovo tipo su Testo ...

Oppure è collegato allo forall su sqlType? Qual è la ragione di questo errore quando tutte le altre istanze vengono derivate automaticamente con successo?

Grazie

risposta

6

Questo sembra molto simile ad alcuni degli esempi (in particolare la Vector uno) nella wiki Roles2 pagina GHC delle cose che non funzionano con il sistema attuale ruolo, ahimè.

Fondamentalmente il problema è che in

class PersistField a => PersistFieldSql a where 
    sqlType :: Monad m => m a -> SqlType 

monade m potrebbe essere istanziata con un costruttore di tipo il cui argomento è ruolo nominale, in modo che m Markdown e m MarkdownNewTnon sono identicamente rappresentata anche se Markdown e MarkdownNewT essi stessi sono - e l'attuale sistema di ruolo non ha modo di limitare m a disabilitare tali costruttori di tipi.

+0

Hai assolutamente ragione. In persistente 2, siamo passati all'utilizzo di Proxy esattamente per questo motivo. –

+0

Ørjan Johansen, grazie, mi sono imbattuto in questo, ma la tua spiegazione semplice e concisa mi ha davvero aiutato! – jcristovao

+0

Michael, quindi la soluzione per ora sarebbe quella di definire PersistFieldSql manualmente o utilizzare Persistent 2, giusto? – jcristovao