haskell中类型的等价表示(2)–Sum

前面给了一个Product的等价表示,还有一种是Sum的。

同样的先给出两种表示。

表示:

data S a b =  L a | R b

等价的表示:

newtype S' a b = S' { unS' :: forall r. (a -> r) -> (b -> r) -> r }

证明:

这里对于S’,forall r限制了可能的值。由于r不可知,所有只能是下面的两种形式:

sl = \f g -> f x

sr = \f g -> g y

可以证明:

sl id g' == id x == x

sr f' id == id y == y

这里g’和f’未知,但是我们可以用不定点来替代。

g' = \_ -> fix id
 
f’ = \_ ->fix id

所以递归的表示为:

sl = \f g -> f (sl id (\_ -> fix id))

sr = \f g -> g (sr (\_ ->fix id) id)

剩下的给出一一映射关系:

toS' :: S a b -> S' a b
toS' (L a) = S' (\f g -> f a)
toS' (R b) = S' (\f g -> g b)

反方向比较麻烦一点,我们需要判断是S'两种形式的哪一种。

我们给出一个helper函数toTrue和toFalse,用它们来test我们的S'表示,由此来判断是哪种。

toTrue :: a -> Bool
toTrue _ = True

toFalse :: a -> Bool
toFalse _ = False
fromS' :: S' a b -> S a b
fromS' (S' s) = case (s toTrue toTrue) == (s toFalse toTrue) of
                        True -> R (s (\_ ->fix id) id)
                        False -> L (s id (\_ ->fix id))

好了,剩下的不证明了。 :)

结论:

有了RankNTypes,代数数据结构不是必须的。(结论太早?没有考虑递归的代数数据结构:))

后面会谈谈free monad的非代数数据结构表示,因为Free monad可以看成是很多层的数据包装,所以等价的函数表示会跟高效。

转载于:https://www.cnblogs.com/ski-comb/p/4361401.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值