gpt4 book ai didi

haskell - SOP表示转换后如何从类型中获取数据类型信息?

转载 作者:行者123 更新时间:2023-12-02 17:01:52 24 4
gpt4 key购买 nike

我正在尝试对数据类型名称进行一些浅层打印,但我不确定如何使用 Generics-SOP 执行此操作。

对于我有新类型列表的情况,我可以相当轻松地打印出我需要的内容:

class GTypeName f where
gtypeName :: g f -> String

instance (HasDatatypeInfo a) => GTypeName (SOP I ('[ '[], '[a, [a]] ])) where
gtypeName _ = "(Array " ++ name ++ ")"
where
name = datatypeName $ datatypeInfo (Proxy @ a)

如您所见,我正在匹配 List 类型并使用内部 a 的数据类型信息来获取名称。但我不知道如何处理我想获取实际的顶级构造函数名称本身的情况。

在 GHC 泛型中,我执行了以下操作:

instance (GTypeName f) => GTypeName (D1 m f) where -- peer inside
gtypeName _ = gtypeName (Proxy @ f)

-- go into the Cons constructed type
instance {-# OVERLAPPING #-} (GTypeName f) => GTypeName (C1 ('MetaCons ":" g s) f) where
gtypeName _ = gtypeName (Proxy @ f)

-- return the constructor name here
instance (KnownSymbol n) => GTypeName (C1 ('MetaCons n g s) f) where
gtypeName _ = symbolVal (Proxy @ n)

-- take the left side, as this is the result of a type product from Cons
instance (GTypeName a) => GTypeName (a :*: b) where
gtypeName _ =
gtypeName (Proxy @ a)

-- match on array and take it out here
instance (GTypeName b) => GTypeName ((C1 ('MetaCons "[]" g s) f) :+: b) where
gtypeName _ = "(Array " ++ gtypeName (Proxy @ b) ++ ")"

这最终与新类型和某些数据类型一起使用,如下所示:

newtype Status = Status Text

newtype OpenRequest = OpenRequest
{ path :: Path
}

data Route req res = Route
{ method :: Method
, url :: Url
}

open :: Route OpenRequest Success
open = Route {method = POST, url = Url "/api/open"}

最佳答案

您可以使用 generics-sop 获取值的顶级构造函数名称,如下所示:

constructor ::
forall a .
(Generic a, HasDatatypeInfo a) => a -> String
constructor a =
hcollapse $
hzipWith
(\ con _args -> K (constructorName con))
(constructorInfo (datatypeInfo (Proxy @a)))
(unSOP $ from a)

这里,constructorInfo ... 为您提供一个包含相关数据类型的所有构造函数名称的产品。然后,hzipWith 调用会选择给定值 a 所属的构造函数。

示例:

GHCi> constructor True
"True"
GHCi> constructor (Just 3)
"Just"
GHCi> constructor [1,2,3]
":"

不幸的是,我并不完全清楚你想用列表类型做什么,所以我无法展示如何将其与你已有的代码结合起来。

关于haskell - SOP表示转换后如何从类型中获取数据类型信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44872179/

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