3
我想在數據類型名稱上做一些淺印刷,但我不知道如何用Generics-SOP做到這一點。如何從SOP表示轉換後的類型獲取數據類型信息?
對於在那裏我有我的NEWTYPE的列表的情況下,我可以打印出什麼,我很容易需要:
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)
正如你所看到的,我匹配名單上的種類和使用內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和一些數據類型,像這樣:
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"}
對不起,意識到我的標題中的問題與身體內容完全不同,但後來我發現由於我只是用數據類型調用我的方法,所以我可以用較少的解決方法逃脫。謝謝!我有我的回購在這裏我現在試圖將ExtractFields實例轉換爲SOP在這裏:https://github.com/justinwoo/godawful-purescript-codegen-demo – kakigoori