Haskell——从具体类型实例获取 TypeRep

发布于 2024-11-05 20:42:23 字数 407 浏览 8 评论 0原文

我想编写一个具有此类型签名的函数:

getTypeRep :: Typeable a => t a -> TypeRep

其中 TypeRep 将是 a 的类型表示,而不是 t a 的类型表示。也就是说,编译器应该在任何调用站点自动返回正确的类型表示形式 [to getTypeRep],这将具有 a 的具体类型。

为了添加一些上下文,我想创建一个“动态类型”数据类型,其特点是它将记住顶级类型,但不记住其参数。例如,我想将MyClass a转换为Dynamic MyClass,上面的函数将用于创建存储a的Dynamic MyClass实例类型参数a的表示。

I want to write a function with this type signature:

getTypeRep :: Typeable a => t a -> TypeRep

where the TypeRep will be the type representation for a, not for t a. That is, the compiler should automatically return the correct type representation at any call sites [to getTypeRep], which will have concrete types for a.

To add some context, I want to create a "Dynamic type" data type, with the twist that it will remember the top-level type, but not its parameter. For example, I want to turn MyClass a into Dynamic MyClass, and the above function will be used to create instances of Dynamic MyClass that store a representation of the type parameter a.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

用心笑 2024-11-12 20:42:23

好吧,如何使用作用域类型变量来选择内部组件:

{-# LANGUAGE ExplicitForAll #-}
{-# LANGUAGE ScopedTypeVariables #-}

import Data.Dynamic
import Data.Typeable

getTypeRep :: forall t a . Typeable a => t a -> TypeRep
getTypeRep _ = typeOf (undefined :: a)

对我有用:

*Main> getTypeRep (Just ())
()
*Main> getTypeRep (Just 7)
Integer
*Main> getTypeRep ([True])
Bool

有趣的设计。

Well, how about using scoped type variables to select the inner component:

{-# LANGUAGE ExplicitForAll #-}
{-# LANGUAGE ScopedTypeVariables #-}

import Data.Dynamic
import Data.Typeable

getTypeRep :: forall t a . Typeable a => t a -> TypeRep
getTypeRep _ = typeOf (undefined :: a)

Works for me:

*Main> getTypeRep (Just ())
()
*Main> getTypeRep (Just 7)
Integer
*Main> getTypeRep ([True])
Bool

Interesting design.

私藏温柔 2024-11-12 20:42:23

与 Don 的解决方案无关的是,请注意代码很少需要 ScopedTypeVariables。它只是使解决方案更清洁(但便携性较差)。没有作用域类型的解决方案是:

{-# LANGUAGE ExplicitForAll #-}
import Data.Typeable

helper :: t a -> a
helper _ = undefined

getTypeRep :: forall t a. Typeable a => t a -> TypeRep
getTypeRep = typeOf . helper

On a tangential note to Don's solution, notice that code rarely require ScopedTypeVariables. It just makes the solution cleaner (but less portable). The solution without scoped types is:

{-# LANGUAGE ExplicitForAll #-}
import Data.Typeable

helper :: t a -> a
helper _ = undefined

getTypeRep :: forall t a. Typeable a => t a -> TypeRep
getTypeRep = typeOf . helper
债姬 2024-11-12 20:42:23

此函数(现在)存在于 Data.Typeable typeRep

This function (now) exists in Data.Typeable typeRep

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文