gpt4 book ai didi

haskell - 使用泛型生成关于 newtype 的文档

转载 作者:行者123 更新时间:2023-12-04 11:35:13 26 4
gpt4 key购买 nike

我有一个 Haskell 项目,它使用了几个 newtypes .
我想导出这些表格,因此我可以将它包含在我的文档(非黑线鳕)中,例如作为 Markdown 表。我对此并不熟悉,但通过阅读,我的计划是使用 Generics/Data.Data , 创建一些大致如下所示的函数:

data MyRowRepresentation = MyRowRepresentation
String -- Name of the newtype
String -- Name of the type its wrapping

toDocRow :: (Generic a, HasDatatypeInfo a) -> (Proxy a) -> MyRowRepresentation
toDocRow = <the part I'm struggling with>

newtype MyType0 = MyType0 Int16
newtype MyType1 = MyType0 Int8
newtype MyType2 = MyType0 Int32
newtype MyType3 = MyType0 Word8

main = do
let table = [
toDocRow (Proxy::MyType0),
toDocRow (Proxy::MyType1),
toDocRow (Proxy::MyType2),
toDocRow (Proxy::MyType3),
]
-- Do something to write `table` to disk.

但是,我很难理解 Generics/Data.Data与构造函数交互。这是我第一次使用 Haskell 区域,所以我尝试了以下代码,只是为了看看它是如何工作的:
{-# LANGUAGE DeriveGeneric #-}
module TmpTmpExport where

import RIO
import RIO.List.Partial (head)
import Text.Show.Pretty
import Data.String.Conversions (cs)
import Data.Data


newtype MyNewType = MyNewType Integer
deriving (Show)
deriving (Data, Typeable)

main :: IO ()
main = do
traceM $ cs $ "INSTANCE: " ++ (show $ dataTypeConstrs $ dataTypeOf $ (MyNewType 0))
traceM $ cs $ "INSTANCE constrType: " ++ (show $ constrType $ head $ dataTypeConstrs $ dataTypeOf $ (MyNewType 0))
traceM $ cs $ "INSTANCE constrType: " ++ (show $ dataTypeConstrs $ constrType $ head $ dataTypeConstrs $ dataTypeOf $ (MyNewType 0))
traceM $ cs $ "INSTANCE constrType: " ++ (show $ (fmap showConstr) $ dataTypeConstrs $ constrType $ head $ dataTypeConstrs $ dataTypeOf $ (MyNewType 0))
traceM $ cs $ "INSTANCE constrType: " ++ (show $ dataTypeConstrs $ constrType $ head $ dataTypeConstrs $ constrType $ head $ dataTypeConstrs $ constrType $ head $ dataTypeConstrs $ dataTypeOf $ (MyNewType 0))



return ()

这给出了以下输出:
INSTANCE: [MyNewType]
INSTANCE constrType: DataType {tycon = "MyNewType", datarep = AlgRep [MyNewType]}
INSTANCE constrType: [MyNewType]
INSTANCE constrType: ["MyNewType"]
INSTANCE constrType: [MyNewType]
我不认为我在一百万英里之外,而是通过阅读 Data.Data 的文档,并尝试了各种功能,我不知道如何使用 dataTypeConstrs 来“进入”新类型。和 constrType ,以便我可以创建 table像这样的行:
table = [
(MyRowRepresentation "Type0" "Int16"),
(MyRowRepresentation "Type1" "Int8")
(MyRowRepresentation "Type2" "Int32")
(MyRowRepresentation "Type3" "Word8")
]
我在概念上是否遗漏了 newtype 之间的区别?和 data , 这可能与 Data.Data 有关吗? ,或者我应该查看不同的工具/库?

最佳答案

你绝对可以用 GHC.Generics 做到这一点.我不太熟悉 Data.Data .
简单的方法,使用 coercible-utils >= 0.1.0 :

import CoercibleUtils.Newtype

toDocRow :: forall a o proxy. (Newtype a o, Typeable a, Typeable o) => proxy a -> MyRowRepresentation
toDocRow _ = MyRowRepresentation
(show (typeRep (Proxy :: Proxy a)))
(show (typeRep (Proxy :: Proxy o)))
此版本坚持实际的新类型,而不是单构造函数数据类型。

这是您如何使用 Generic 推出自己的产品的方法.实例将用于 M1K1 .我的第一个想法是你应该使用 Typeable在最外面(在打开通用表示之前)获取新类型名称,然后使用无聊的实例忽略 M1层,然后对 K1 再次使用 Typeable获取包装的类型信息。在外部,您可以改为使用附加到最外层 M1 的元数据。 ,但这似乎更尴尬。
请注意,可以使用 TypeApplications 稍微清理以下内容而不是代理传递。
{-# language DeriveGeneric, FlexibleContexts, ScopedTypeVariables, KindSignatures #-}
import GHC.Generics
import Data.Typeable
import Data.Int
import Data.Word
import Data.Kind (Type)

data MyRowRepresentation = MyRowRepresentation
String -- Name of the newtype
String -- Name of the type its wrapping
deriving Show

toDocRow :: forall a proxy. (Generic a, Typeable a, Grump (Rep a)) => proxy a -> MyRowRepresentation
toDocRow _ = MyRowRepresentation
(show (typeRep (Proxy :: Proxy a)))
(show $ grump (Proxy :: Proxy (Rep a)))

class Grump (f :: Type -> Type) where
grump :: Proxy f -> TypeRep

instance Grump f => Grump (M1 i c f) where
grump _ = grump (Proxy :: Proxy f)

instance Typeable c => Grump (K1 i c) where
grump _ = typeRep (Proxy :: Proxy c)

newtype MyType0 = MyType0 Int16
deriving Generic
newtype MyType1 = MyType1 Int8
deriving Generic
newtype MyType2 = MyType2 Int32
deriving Generic
newtype MyType3 = MyType3 Word8
deriving Generic

main = do
let table = [
toDocRow (Proxy:: Proxy MyType0),
toDocRow (Proxy:: Proxy MyType1),
toDocRow (Proxy:: Proxy MyType2),
toDocRow (Proxy:: Proxy MyType3)
]
print table

关于haskell - 使用泛型生成关于 newtype 的文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67974762/

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