在snap中使用具有持久数据类型的类型安全路由

时间:2015-08-08 22:36:15

标签: haskell persistent haskell-snap-framework

我有一个使用Persistent存储的Snap应用程序,我试图为Persistent中定义的数据类型生成类型安全路由。我正在使用snap-web-routes package

我有以下模板Haskell函数,它创建GroupGroupId的数据类型:

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
  Group
    name T.Text
    deriving Show
|]

Application.hs我有:

data AppUrl = AddLink GroupId deriving (Eq, Show, Read, Generic)

该文件表明:

instance PathInfo AppUrl

是我需要做的,只要上面的Generic推导,然而这会爆发

No instance for (PathInfo (KeyBackend SqlBackend Group))
      arising from a use of ‘Web.Routes.PathInfo.$gdmtoPathSegments’

我的假设是这个错误表明Haskell不知道如何使用Persistent的数据类型自动创建实例定义。

我的下一次尝试是手动定义实例:

instance PathInfo AppUrl where
  toPathSegments   (AddLink groupId) = "add-link" : toPathPiece groupId : []
  fromPathSegments (x:y:[]) = ????

我似乎无法弄清楚如何构建GroupId数据类型。

来自Yesod的优秀Persistent tutorial我知道数据类型定义为:

type GroupId = Key Group
newtype Key Group = GroupKey (BackendKey SqlBackend)

但后来我遇到了一个问题,因为BackendKey没有公开,所以我无法导入它并创建我自己的实例。我似乎无法找到一个公共API来在Persistent中创建这种数据类型。

1 个答案:

答案 0 :(得分:1)

The documentation for SqlBackend显示关联的数据类型BackendKey已为SqlBackend实例化为

data BackendKey SqlBackend = SqlBackendKey {
    unSqlBackendKey :: Int64
}

根据以下示例的说明,编写自己的PathInfo实例应该是足够的信息:

{-# LANGUAGE TypeFamilies #-}

import Database.Persist.Sql
import Data.Int (Int64)

foo :: BackendKey SqlBackend -> Int64
foo (SqlBackendKey key) = key

bar :: Int64 -> BackendKey SqlBackend
bar = SqlBackendKey