2013-12-23 30 views
2

在我的应用程序中,我的数据模型有几个不同的使用Integer或String作为标识符的实例。为了安全起见,我已经先行一步,并包裹这些标识符为NEWTYPE声明如下所示:需要为Yesod路径定义什么类型的类?

newtype DocId = DocId Integer 
newtype GroupName = GroupName String 
newtype UserName = UserName String 

当我建立我的耶索德路径,我发现,我要为每一个至少三个实例这些实例几乎总是相同的

instance Read DocId where 
    readsPrec prec val = case reads val of 
     (i, ""):_ -> [(DocId i, "")] 
     [] -> [] 

instance B.ToMarkup DocId where 
    toMarkup (DocId val) = B.toMarkup val 

instance PathPiece DocId where 
    toPathPiece (DocId i) = T.pack $ show i 
    fromPathPiece s = 
     case reads $ T.unpack s of 
      (i, ""):_ -> Just i 
      [] -> Nothing 

这段文字一遍又一遍。

为了在URL中呈现我的数据类型(如@ {ViewDocument docId})并且能够解析这些URL,我真的需要设置什么?

回答

4

如果您打开GeneralizedNewtypeDeriving,则只需在每个新数据类型下添加deriving PathPiece,如果无法直接导出数据类型,则可以添加deriving instance PathPiece DocId

对于要成为路由一部分的每个数据类型,您都需要Read,Show和PathPiece实例。

+0

其实,我不能那样做,因为我在应用程序中进行了严格的分离。我声明大部分数据类型的地方都在一个根本不知道Yesod的库中。 –

+0

您可以等效使用独立派生:派生实例PathPiece DocId。但是,您确实无法在类型的声明站点导入“Web.PathPieces”?我个人更喜欢这样做来创建孤立实例。 –

+0

孤儿实例实际上开始令我非常恼火。但是我的核心库代表了应用程序的“无头”实现,甚至没有依赖任何web工具。我部署的应用程序导入了我的核心库和Yesod。不过,独立派生很有效。我不知道这是可以做到的。有点像我不知道如何定义可以派生的数据类型。 –

0

基于一些试验和错误(即删除功能和看到的休息时间),它看起来像,以便数据类型是一个耶索德路径的一部分,它需要被定义了三种类型类:

  • 显示上述
  • PathPiece

我ToMarkup声明适用于我如何在HTML(哈姆雷特,火焰,什么,但对我来说哈姆雷特)显示我的数据类型。因此,如果我只将数据类型放入URL中,则不是必需的。

相关问题