[英]How does `HFix` work in Haskell's multirec package?
我了解常规定点类型组合器,并且我了解高阶定n型组合器,但是HFix
我HFix
。 您能否举一个可以应用HFix
的数据类型及其固定点的HFix
。
自然的参考是针对互递数据类型的具有固定点的通用编程,其中解释了multirec包 。
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)
让我们介绍该数据类型的特定于家庭的GADT,如第4.1节所述
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
这些用作I的HFunctor
实例的约束。
现在让我们为偶数和奇数数据类型定义模式函子。 我们使用库中的组合器。 :>:
类型构造函数使用类型索引标记值:
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同构,并且如果将其hto
Fam
的实例,则可以使用hfrom
和hto
函数 :
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
和Odd
为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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.