如何通过'TypeRep'指定值的类型?

err*_*rom 1 polymorphism haskell types dynamic generic-programming

我的目标是编写带有一些多态值的函数,并列出表示具体类型的typereps.它返回具有相同值的新列表,但已经转换为通过typereps指定的具体类型.

让我们有值的这种列表:["one", "two"]与-XOverloadedStrings启用.
每个的类型分别是IsString a => a.

我们可以通过这种方式获得的类型的列表:

import Data.Typeable (Proxy(..), typeRep)
import Data.Text     (Text)

[typeRep (Proxy :: Proxy String), typeRep (Proxy :: Proxy ByteString)]
Run Code Online (Sandbox Code Playgroud)

有没有办法获得"one"类型String和"two"类型ByteString?

PS为了防止根据包含不同类型值的列表的错误,我们可以包装每个值Dynamic.,如下例所示(伪代码):

 {-# LANGUAGE ParallelListComp #-}

 import Data.Dynamic (toDyn)

 [ toDyn (val :: type') | val <- vals | type' <- concreteTypes ]
Run Code Online (Sandbox Code Playgroud)

它可以使用Template Haskell完成,但它太难看了.

dfe*_*uer 5

我无法想象你的目的,但代码可能看起来像这样.我正在使用新Type.Reflection界面,因为我对它比对经典更熟悉Data.Typeable,但这也适用于此.

import Type.Reflection

types :: [SomeTypeRep]
types = [SomeTypeRep (typeRep @String), SomeTypeRep (typeRep @Text)]

strings :: [String]
strings = ["one", "two"]

converted :: [Dynamic]
converted = fromJust $ zipWithM convert types strings

convert :: SomeTypeRep -> String -> Maybe Dynamic
convert (SomeTypeRep rep) s
  | Just HRefl <- eqTypeRep rep (typeRep @String) = Just $ toDynamic s
  | Just HRefl <- eqTypeRep rep (typeRep @Text) = Just $ toDynamic (fromString s)
  | otherwise = Nothing
Run Code Online (Sandbox Code Playgroud)