昨天我尝试使用GHC.Generics回答this question about a representation for a datatype.。我可以恢复给出的示例问题的类型定义,例如:
data Artist = Artist Text Genre
data Genre = Jazz | Metal
使用派生的Generic
实例,Modelable
的默认实例(可以恢复其类型定义的事物类)和Modelable
的{{1}}实例
Text
我们可以确定deriving instance Generic Artist
instance Modelable Artist
deriving instance Generic Genre
instance Modelable Genre
具有前面类型声明的undefined :: Artist
类型:
Main.Artist
我用声明来表示类型,这样我们也可以攻击像
这样的递归数据结构data Main.Artist :: *
Artist Data.Text.Text Main.Genre
data Main.Genre :: *
Jazz
Metal
Main.Artist
我们可以确定
data ExampleTree = Branch Int ExampleTree ExampleTree | Leaf
到目前为止,我所拥有的代码涵盖了所有这些案例:
https://gist.github.com/Cedev/9857191
我们可以恢复类型应用中的类型吗?
现在我无法区分应用于两种不同类型的类型,例如data Main.ExampleTree :: *
Branch GHC.Int.Int Main.ExampleTree Main.ExampleTree
Leaf
Main.ExampleTree
和[Track]
。从String ~ [Char]
Datatype
D
实例我只能恢复外部类型,在这种情况下GHC.Types.[]
,我甚至无法区分这两种类型。
data Album = Album Artist [Track]
data Track = Track Int String
以下是Album
类型的可接受输出,但效率低下:
data GHC.Types.[] GHC.Char.Char :: *
[]
: GHC.Char.Char GHC.Types.[]
data GHC.Types.[] Main.Track :: *
[]
: Main.Track GHC.Types.[]
data Main.Album :: *
Album Main.Artist (GHC.Types.[] Main.Track)
data Main.Artist :: *
Artist Data.Text.Text Main.Genre
data Main.Genre :: *
Jazz
Metal
data Main.Track :: *
Track GHC.Int.Int (GHC.Types.[] GHC.Char.Char)
Main.Album
由于我无法区分[Track]
和String
之间的区别,我能得到的最接近的是这样的,它假设所有[]
都包含Track
因为那是第一次遇到的:
data GHC.Types.[] :: *
[]
: Main.Track GHC.Types.[]
data Main.Album :: *
Album Main.Artist GHC.Types.[]
data Main.Artist :: *
Artist Data.Text.Text Main.Genre
data Main.Genre :: *
Jazz
Metal
data Main.Track :: *
Track GHC.Int.Int GHC.Types.[]
Main.Album
我们可以在声明中恢复类型变量吗?
更好的表现形式将分享[]
的定义。这需要发现[]
具有种类* -> *
,并且其:
构造函数的第一个参数的类型来自[]
的类型参数。
data GHC.Types.[] :: * -> *
[]
: (Var 0) GHC.Types.[]
data Main.Album :: *
Album Main.Artist (GHC.Types.[] Main.Track)
data Main.Artist :: *
Artist Data.Text.Text Main.Genre
data Main.Genre :: *
Jazz
Metal
data Main.Track :: *
Track GHC.Int.Int (GHC.Types.[] GHC.Char.Char)
Main.Album
我们能否为*
和* -> *
以外的其他类型的内容恢复类型定义?
是否可以恢复具有更多参数的事物的定义?
data ThreeTuple a b c = ThreeTuple a b c
应该是例如
data Module.ThreeTuple :: * -> * -> * -> *
ThreeTuple (Var 0) (Var 1) (Var 2)
是否有可能恢复具有更高阶种类的东西的定义?
data Position f = {
positionName :: f String
}
data Employee f = {
employeeName :: f String,
employeePosition :: f (Position f)
}
哪个是
data Module.Position :: (* -> *) -> *
Position {
positionName :: (Var 0) (GHC.Types.[] GHC.Char.Char)
}
data Module.Employee :: (* -> *) -> *
Employee {
employeeName :: (Var 0) (GHC.Types.[] GHC.Char.Char),
employeePosition :: (Var 0) (Module.Position (Var 0))
}