GeneralizedNewtypeDeriving fails for PersistFieldSql

女生的网名这么多〃 提交于 2019-12-07 04:05:53

问题


I'm trying to define a Markdown newtype, and using GeneralizedNewtypeDeriving to automatically define new instances:

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

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

This fails for the PersistFieldSql with the following message:

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’

Is this due to the new roles features of GHC 7.8.2? In that particular case I don't know what to do, since Markdown is itself a newtype over Text...

Or is this related with the forall on sqlType? What is the reason for this error when all other instances are successfully automatically derived?

Thanks


回答1:


This looks very similar to some of the examples (in particular the Vector one) in the GHC wiki Roles2 page of things that don't work with the current role system, alas.

Basically the problem is that in

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

the monad m might be instantiated with a type constructor whose argument has nominal role, so that m Markdown and m MarkdownNewT aren't identically represented even if Markdown and MarkdownNewT themselves are - and the current role system has no way of restricting m to disallow such type constructors.



来源:https://stackoverflow.com/questions/25893150/generalizednewtypederiving-fails-for-persistfieldsql

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!