首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Haxl中的代码重用-避免GADT构造函数-每个请求类型

Haxl中的代码重用-避免GADT构造函数-每个请求类型
EN

Stack Overflow用户
提问于 2018-01-15 01:22:23
回答 1查看 121关注 0票数 2

Haxl是一个令人惊叹的库,但我发现的一个主要痛点是,每种对数据源的请求都需要在请求GADT中使用自己的构造函数。例如,以tutorial中的示例

代码语言:javascript
复制
data BlogRequest a where
  FetchPosts       :: BlogRequest [PostId]
  FetchPostContent :: PostId -> BlogRequest PostContent

然后对每个构造函数进行模式匹配,并在DataSource实例的match函数中单独处理。这种风格为非平凡的应用程序带来了大量的样板。以使用关系数据库的应用程序为例,其中每个表都有一个主键。可能有数百个表,所以我不想为每个表定义一个构造函数(更不用说所有可能的表连接了…)。我真正想要的是:

代码语言:javascript
复制
data DBRequest a where
  RequestById :: PersistEntity a => Key a -> DBRequest (Maybe a)

我使用persistent从我的表中创建类型,但这不是一个关键的细节--我只想为多个可能的返回类型使用一个构造函数。

当尝试编写fetch函数时,问题就出现了。使用Haxl的通常过程是在构造函数上进行模式匹配,以分离出各种类型的BlockedFetch请求,在上面的示例中,这将对应于以下内容:

代码语言:javascript
复制
        resVars :: [ResultVar (Maybe a)]
        args :: [Key a]
        (psArgs, psResVars) = unzip
            [(key, r) | BlockedFetch (RequestById key) r <- blockedFetches]

SQL会(以某种方式)将参数按键类型分组,并为每个组分派一个...then查询。但这种方法不会,因为这里可能会有对多个PersistentEntity类型(即数据库表)的请求,其中每一个都是不同类型的a,因此构建列表是不可能的。我考虑过使用存在量化的类型来解决这个问题(类似于单例库中的SomeSing ),但是如果不对每个可能的表/类型进行模式匹配,就无法根据需要对请求进行分组。

有什么方法可以实现这种代码重用吗?

EN

回答 1

Stack Overflow用户

发布于 2018-01-20 09:19:25

我认为有两种方法:

Typeable

代码语言:javascript
复制
data DBRequest a where
  RequestById :: (Typeable a, PersistEntity a) => Key a -> DBRequest (Maybe a)

或GADT "tag“类型:

代码语言:javascript
复制
data Tag a where
    TagValue1 :: Tag Value1
    TagValue2 :: Tag Value2
    TagValue3 :: Tag Value3
    TagValue4 :: Tag Value4
    TagValue5 :: Tag Value5

data DBRequest a where
  RequestById :: PersistEntity a => Tag a => Key a -> DBRequest (Maybe a)

这些模式非常相似,特别是在使用GHC-8.2和https://hackage.haskell.org/package/base-4.10.1.0/docs/Type-Reflection.html (用TypeRep a替换Tag a )的情况下。

无论哪种方式,您都可以使用标记对Key a进行分组。我还没有尝试过,但是dependent-map可能会很方便:http://hackage.haskell.org/package/dependent-map

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48252190

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档