Yesod/Persistent 实体派生 Show

Posted

技术标签:

【中文标题】Yesod/Persistent 实体派生 Show【英文标题】:Yesod/Persistent entity deriving Show 【发布时间】:2012-12-31 04:58:32 【问题描述】:

在Persistent chapter of the Yesod book中,给出了这个实体的例子

-# LANGUAGE QuasiQuotes, TypeFamilies, GeneralizedNewtypeDeriving, TemplateHaskell, OverloadedStrings, GADTs #-
import Database.Persist
import Database.Persist.TH
import Database.Persist.Sqlite
import Control.Monad.IO.Class (liftIO)

mkPersist sqlSettings [persist|
Person
    name String
    age Int
    deriving Show
|]

生成代码

-# LANGUAGE TypeFamilies, GeneralizedNewtypeDeriving, OverloadedStrings, GADTs #-
import Database.Persist
import Database.Persist.Store
import Database.Persist.Sqlite
import Database.Persist.GenericSql.Raw (SqlBackend)
import Database.Persist.EntityDef
import Control.Monad.IO.Class (liftIO)
import Control.Applicative

data Person = Person
     personName :: String
    , personAge :: Int
    
  deriving (Show, Read, Eq)

type PersonId = Key Person

instance PersistEntity Person where
    -- A Generalized Algebraic Datatype (GADT).
    -- This gives us a type-safe approach to matching fields with
    -- their datatypes.
    data EntityField Person typ where
        PersonId   :: EntityField Person PersonId
        PersonName :: EntityField Person String
        PersonAge  :: EntityField Person Int

    type PersistEntityBackend Person = SqlBackend

    toPersistFields (Person name age) =
        [ SomePersistField name
        , SomePersistField age
        ]

    fromPersistValues [nameValue, ageValue] = Person
        <$> fromPersistValue nameValue
        <*> fromPersistValue ageValue
    fromPersistValues _ = Left "Invalid fromPersistValues input"

    -- Information on each field, used internally to generate SQL statements
    persistFieldDef PersonId = FieldDef
        (HaskellName "Id")
        (DBName "id")
        (FTTypeCon Nothing "PersonId")
        []
    persistFieldDef PersonName = FieldDef
        (HaskellName "name")
        (DBName "name")
        (FTTypeCon Nothing "String")
        []
    persistFieldDef PersonAge = FieldDef
        (HaskellName "age")
        (DBName "age")
        (FTTypeCon Nothing "Int")
        []

为什么将deriving Show 添加到Person 实体会生成所有三个类型类(Show, Read, Eq) 的派生?我对 Haskell 和 Yesod 很陌生,所以如果很明显,我很抱歉,但我在任何地方都找不到答案!这只是文档中的错误吗?谢谢!

【问题讨论】:

【参考方案1】:

简单:这是书中的错字:)。如果您查看实际生成的代码(使用-ddump-splices),您会发现它实际上只是派生了Show 实例。

【讨论】:

看来修复这本书是值得的。 1.4版还是这样的。 谢谢,我以为我已经解决了这个问题,但显然没有。它现在是最新的。

以上是关于Yesod/Persistent 实体派生 Show的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Yesod / Persistent 中正确使用 runDB

如何使用 Yesod/Persistent 创建外键约束?

Yesod / Persistent中的外键约束?

如何使用 Yesod/Persistent 访问两个不同的数据库服务器?

了解 Yesod Persistent TH 生成的代码

Yesod persistent-postgresql rawSql 查询带有列列表通配符会产生语法错误