【发布时间】:2012-04-01 07:39:27
【问题描述】:
我了解常规定点类型组合器,我想我了解高阶定点类型组合器,但 HFix 让我无法理解。您能否举例说明一组数据类型及其(手动派生的)固定点,您可以将HFix 应用于这些固定点。
【问题讨论】:
标签: haskell types generic-programming multirec
我了解常规定点类型组合器,我想我了解高阶定点类型组合器,但 HFix 让我无法理解。您能否举例说明一组数据类型及其(手动派生的)固定点,您可以将HFix 应用于这些固定点。
【问题讨论】:
标签: haskell types generic-programming multirec
自然参考是论文Generic programming with fixed points for mutually recursive datatypes multirec package 解释的地方。
HFix 是用于相互递归数据类型的定点类型组合器。
论文第 3.2 节对此进行了很好的解释,但想法是
概括这种模式:
Fix :: (∗ -> ∗) -> ∗
Fix2 :: (∗ -> ∗ -> ∗) -> (∗ -> ∗ -> ∗) -> ∗
到
Fixn :: ((∗ ->)^n * ->)^n ∗
≈
Fixn :: (*^n -> *)^n -> *
为了限制它在一个固定点上的类型,他们使用类型构造函数 而不是 *^n。他们给出了一个 AST 数据类型的例子,相互递归 论文中的三种类型。我给你也许是最简单的例子。让 我们 HFix 这个数据类型:
data Even = Zero | ESucc Odd deriving (Show,Eq)
data Odd = OSucc Even deriving (Show,Eq)
让我们按照第 4.1 节介绍该数据类型的系列特定 GADT
data EO :: * -> * where
E :: EO Even
O :: EO Odd
EO Even 表示我们携带的是偶数。
我们需要 El 实例才能使其工作,它说明了哪个特定的构造函数
我们在写EO Even和EO Odd时分别指的是。
instance El EO Even where proof = E
instance El EO Odd where proof = O
这些用作HFunctor instance 的约束
为I。
现在让我们为偶数和奇数数据类型定义模式函子。
我们使用库中的组合器。 :>: 类型构造函数标签
带有类型索引的值:
type PFEO = U :>: Even -- ≈ Zero :: () -> EO Even
:+: I Odd :>: Even -- ≈ ESucc :: EO Odd -> EO Even
:+: I Even :>: Odd -- ≈ OSucc :: EO Even -> EO Odd
现在我们可以使用HFix 来围绕这个模式函子打结:
type Even' = HFix PFEO Even
type Odd' = HFix PFEO Odd
这些现在与 EO Even 和 EO Odd 同构,我们可以使用
hfrom and hto functions
如果我们让它成为Fam的实例:
type instance PF EO = PFEO
instance Fam EO where
from E Zero = L (Tag U)
from E (ESucc o) = R (L (Tag (I (I0 o))))
from O (OSucc e) = R (R (Tag (I (I0 e))))
to E (L (Tag U)) = Zero
to E (R (L (Tag (I (I0 o))))) = ESucc o
to O (R (R (Tag (I (I0 e))))) = OSucc e
一个简单的小测试:
test :: Even'
test = hfrom E (ESucc (OSucc Zero))
test' :: Even
test' = hto E test
*HFix> test'
ESucc (OSucc Zero)
另一个用代数将Even 和Odds 转换为Int 值的愚蠢测试:
newtype Const a b = Const { unConst :: a }
valueAlg :: Algebra EO (Const Int)
valueAlg _ = tag (\U -> Const 0)
& tag (\(I (Const x)) -> Const (succ x))
& tag (\(I (Const x)) -> Const (succ x))
value :: Even -> Int
value = unConst . fold valueAlg E
【讨论】:
:>: 上更详细地介绍一下吗,它对我来说仍然很不透明。