我一直在阅读"数据类型点菜"并尝试跟随
:set -XTypeOperators
:m Data.Comp.Ops
:m Data.Comp
type X' a = [] :+: Maybe
type X a = Term (X' a)
因此,X Int应该是一个列表或者可能是Int。但是我没有尝试过的任何东西导致我能够创建X Int类型的值。我也尝试过聪明的构造函数,并且他们抱怨说没有可用的Subsume关系。看看hackage,似乎并不是一个。有人可以解释我如何围绕这个圈子吗?
答案 0 :(得分:1)
您误解了,X Int
不包含Int
类型的值。别名X'
在右侧不使用a
;因此,它必须是幻像类型。对于任何X a
,类型a
包含零个或多个节点(由于[]
)或零或一个节点(由于Maybe
)。请注意,节点或叶子上都没有数据。如果你想要这个树结构,每个'branch'都有数据,你必须在每个分支处添加一个常量:
type X' a = K a :*: ([] :+: Maybe)
newtype K a x = K a
。实际上,这种向签名添加“常量注释”的概念是如此常见,以至于compdata有一个特殊的构造f :&: e
,它与f :*: K e
同构。然后像这样构建它:
import Data.Comp
import Data.Comp.Ops
import Data.Comp.Show
import Data.Comp.Sum
type X' a = ([] :+: Maybe) :&: a
type X a = Term (X' a)
listNode :: a -> [X a] -> X a
listNode x xs = Term $ Inl xs :&: x
mayNode :: a -> Maybe (X a) -> X a
mayNode x mx = Term $ Inr mx :&: x
test = listNode 1
[ mayNode 2 Nothing
, mayNode 3 $ Just $
mayNode 10 $ Just $
listNode 4
[ listNode 10 []
, mayNode 1 Nothing
]
]