Haskell:在编译时引用值的类型

标签 haskell types vinyl

我想知道是否有一种很好的方法来引用值的类型,而无需使用 type 显式地给它们起别名。在代码中(不是在运行时 - 这里没有具体化)。

使用以下代码(使用 Data.Vinyl ):

{-# LANGUAGE DataKinds, TypeOperators #-}

import Data.Vinyl

name = Field :: "name" ::: String
age = Field :: "age" ::: Int
type Person = ["name" ::: String, "age" ::: Int]

这里我们有类型 "name" ::: String"age" ::: Int在两个地方重复。如果我们在多个记录中重用字段,这可能会变成多个地方。尽管 Person类型实际上是指组成字段,类型声明是独立的。所以改变ageFloat 表示比如说,需要在各个地方进行更改。

显然,没有必要显式键入内容,因为它们会被推断出来。但是,在我的情况下,记录类型是从选项解析器返回的,因此是导出的。同样,可以编写以下内容:
type Name = "name" ::: String
name = Field :: Name
type Age = "age" ::: Int
age = Field :: Age
type Person = [Name, Age]

然而,这涉及到另一个类型别名的负载和双倍的行数。我希望能够写的是以下内容:
name = Field :: "name" ::: String
age = Field :: "age" ::: Int
type Person = [typeof name, typeof age]

这显式链接了 Person 的类型到其字段的类型。

有没有办法(最好是 sans-TH,但我什至有兴趣涉及 TH)来做到这一点?

最佳答案

制作 String -> [Name] -> DecsQ 应该很容易。函数出
以下。 ghc7.6(至少)太糟糕了,检查类型中的循环
同义词似乎停止了更漂亮 type Person = $(listOfT ['name, 'age])
锻炼。

{-# LANGUAGE DataKinds, TemplateHaskell, TypeOperators #-}
import Language.Haskell.TH
import Control.Applicative
import Data.Vinyl

name = Field :: "name" ::: String
age = Field :: "age" ::: Int

let listOfT (n:ns) = do
        VarI _ ty _ _ <- reify n
        (appT promotedConsT) (return ty) `appT` listOfT ns
    listOfT [] = promotedNilT
 in return <$> tySynD (mkName "Person") [] (listOfT ['name, 'age])

关于Haskell:在编译时引用值的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21437901/

相关文章:

haskell - 试图理解 Haskell 中的函数应用运算符

haskell - 如何使用 GHCJS 从 Javascript 调用 Haskell

ftp - Gulpvinyl ftp - 删除本地删除的文件

javascript - 如何使用对象列表作为 gulp 源流

haskell - 声明适用于具有特定字段的 Vinyl 记录的约束

haskell - 如何继承Haskell中的Eq类?

haskell - Show Haskell 的实例

scala - 是否有一种内置的更优雅的方式来按元素类型过滤和映射集合?

types - 为什么 Dialyzer 告诉我这个有趣的合约有重叠的域?

haskell - 什么是类型量词?