将类型级别列表转换为值

时间:2015-02-23 03:19:24

标签: haskell ghc type-level-computation

模块GHC.TypeLits目前提供natValsymbolVal,这使我们可以从类型NatSymbol获取运行时值。有没有办法从类型[String]中获取类型'[Symbol]的运行时值?我看不出一个明显的方法来做到这一点。我可以想到一个使用带有OverlappingInstances的类型类的东西,但似乎GHC应该已经有了这个功能。

2 个答案:

答案 0 :(得分:7)

symbolVal可以映射到类型级别列表。为此,除了ScopedTypeVariablesPolyKinds之外,我们还需要DataKindsTypeOperators

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE PolyKinds #-}

import Data.Proxy
import GHC.TypeLits

我们将定义我们可以“获得[String]类型的运行时值”的类型(任何类型)。

class SymbolVals a where
    symbolVals :: proxy a -> [String]

我们可以获得任何类型的空列表的字符串列表。

instance SymbolVals '[] where
    symbolVals _ = []

我们可以获得任何类型列表的字符串列表,其中我们可以获得第一种类型的字符串和剩余字符串的字符串列表。

instance (KnownSymbol h, SymbolVals t) => SymbolVals (h ': t) where
    symbolVals _ = symbolVal (Proxy :: Proxy h) : symbolVals (Proxy :: Proxy t)

答案 1 :(得分:2)

我建议使用singletons库。除了使用Sing代替Proxy类型之外,您拥有所需的一切:

$ stack ghci --package singletons
Configuring GHCi with the following packages: 
GHCi, version 8.0.1: http://www.haskell.org/ghc/  :? for help
Prelude> :set -XDataKinds 
Prelude> import Data.Singletons.Prelude
Prelude Data.Singletons.Prelude> fromSing (sing :: Sing '["a","b"])
["a","b"]
Prelude Data.Singletons.Prelude> :t fromSing (sing :: Sing '["a","b"])
fromSing (sing :: Sing '["a","b"]) :: [String]