gpt4 book ai didi

haskell - 编写与 GHC.Generics 一起使用的类型级函数

转载 作者:行者123 更新时间:2023-12-01 13:51:21 24 4
gpt4 key购买 nike

我正在尝试使用 GHC.Generics 编写一个通用函数,它将返回一个值中使用的所有数据类型名称。

这是我目前所拥有的:

{-# LANGUAGE DefaultSignatures, DeriveGeneric, TypeOperators, FlexibleContexts #-}
{-# LANGUAGE MonomorphismRestriction #-}

module Lib4 where

import GHC.Generics

class Names f where
names' :: f a -> [String]

instance Names U1 where
names' _ = []

instance (Names a, Names b) => Names (a :+: b) where
names' (L1 x) = names' x
names' (R1 x) = names' x

instance (Names a, Names b) => Names (a :*: b) where
names' (a :*: b) = names' a ++ names' b

instance Names (M1 i c a) where
names' (M1 x) = ... -- use datatypeName here?

names x = names' (from x)

唯一缺少的部分是 M1 i c a 实例定义。

如何调用 datatypeName 来获取类型的名称?

我正在关注 Stephan Diehl 的关于泛型的博文“What I Wish I Know...”[1]

[1] http://dev.stephendiehl.com/hask/#generic

最佳答案

第一个提示,如果您还不知道:您可以在 GHCi 中通过 :kind! 查看类型 Rep-s。例如:

> :kind! Rep [Int]
Rep [Int] :: * -> *
= D1
GHC.Generics.D1[]
(C1 GHC.Generics.C1_0[] U1
:+: C1
GHC.Generics.C1_1[]
(S1 NoSelector (Rec0 Int) :*: S1 NoSelector (Rec0 [Int])))

至于实际问题,对于当前作业datatypeName不适用,相反我们可以使用data.Typeable中的typeOf恢复字段类型

{-# LANGUAGE MonomorphismRestriction #-}

import GHC.Generics
import Data.Typeable

class Names f where
names' :: f a -> [TypeRep]

instance Names U1 where
names' _ = []

instance (Names a, Names b) => Names (a :+: b) where
names' (L1 x) = names' x
names' (R1 x) = names' x

instance (Names a, Names b) => Names (a :*: b) where
names' (a :*: b) = names' a ++ names' b

instance Names f => Names (M1 i c f) where
names' (M1 fa) = names' fa

instance (Typeable t) => Names (Rec0 t) where
names' (K1 x) = [typeOf x]

names x = names' (from x)

例子:

> data Foo = Foo Int Bool () deriving (Generic)
> names $ Foo 0 True ()
[Int,Bool,()]

请注意,虽然此实现不是递归的,但它只查看最顶层构造函数的字段。

> names [0, 1]
[Integer, [Integer]]

递归版本将涉及更多的机制,因为某些类型的表示很容易导致天真的实现中的无限循环,因此我们必须跟踪访问过的字段。

关于haskell - 编写与 GHC.Generics 一起使用的类型级函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31446425/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com