我想只使用这种类型定义来定义列表:
data Unit = Unit
data Prod a b = P a b
data Sum a b = L a | R b
newtype Mu f = Mu (forall a . (f a -> a) -> a)
我成功地定义了自然数,如下所示:
zeroMu = Mu $ \f -> f $ L Unit
succMu (Mu g) = Mu $ \f -> f $ R $ g f
我知道如何借助额外的数据类型来定义列表:
data ListF a x = NilF | ConsF a x
nilMu' = Mu $ \f -> f $ NilF
consMu' x (Mu g) = Mu $ \f -> f $ ConsF x $ g f
我能得到的“更好”是这样,但它不进行类型检查(预期类型是 µL.(1+(a*L))):
nilMu = Mu $ \f -> f $ L Unit
consMu x (Mu g) = Mu $ \f -> f $ R $ P x $ g f
如何仅定义nilMu
和consMu
使用先前定义的类型及其构造函数?
编辑
正如@chi answer解释的那样,可以定义 anewtype
如下:
newtype F a x = F (Sum Unit (Prod a x))
nilMu = Mu $ \f -> f $ F $ L Unit
consMu x (Mu g) = Mu $ \f -> f $ F $ R $ P x $ g f
它进行类型检查,但需要定义一个新类型。
这个问题的目的是用单位、乘积、总和和递归类型扩展一个简单类型的组合逻辑。前三种类型很容易实现,引入了 7 个新的组合子(unit
, pair
, first
, second
, left
, right
, case
)。递归类型似乎也很容易实现,只需添加一个类型构造函数组合器mu
,但正如这个问题所示,如果没有额外的语言构造,它就不够灵活。
这个问题有解决方案吗?是否有递归类型的组合逻辑可供参考?