模块GHC.TypeLits目前提供natVal
和symbolVal
,这使我们可以从类型Nat
或Symbol
获取运行时值。有没有办法从类型[String]
中获取类型'[Symbol]
的运行时值?我看不出一个明显的方法来做到这一点。我可以想到一个使用带有OverlappingInstances
的类型类的东西,但似乎GHC应该已经有了这个功能。
答案 0 :(得分:7)
symbolVal
可以映射到类型级别列表。为此,除了ScopedTypeVariables
和PolyKinds
之外,我们还需要DataKinds
和TypeOperators
。
{-# 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]