首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有没有可能用RankNTypes简化Cont的定义?

有没有可能用RankNTypes简化Cont的定义?
EN

Stack Overflow用户
提问于 2019-09-24 17:31:00
回答 1查看 102关注 0票数 3

我正在阅读在Haskell中延续的this implementation,我发现它很棘手,大多数时候,r并不是那么重要,所以我们提供了reset来让它更容易被替换。

因此,我认为Cont r a中的r类型变量没有必要公开,也许我们可以只使用forall rr隐藏在Cont的定义中,所以下面是我的尝试:

代码语言:javascript
复制
{-# language RankNTypes #-}

data Cont a = MkCont {runCont :: forall r. (a -> r) -> r}

-- try to construct a Cont
c1 :: Cont Int
c1 = MkCont ($ 1)

evalCont :: Cont a -> a
evalCont c = runCont c id

-- mapCont is useless since `f` can only be `id` now
mapCont :: (forall r. r -> r) -> Cont a -> Cont a
mapCont f c = (MkCont (f . runCont c))

withCont :: (forall r. (b -> r) -> a -> r) -> Cont a -> Cont b
withCont f c = MkCont (runCont c . f)

-- reset is unnecessary since `r` is hidden
reset :: Cont a -> Cont a
reset = id

shift :: (forall r. (a -> r) -> Cont r) -> Cont a
shift f = MkCont (evalCont . f)

-- don't know how to define `callCC` now ...
callCC :: ((a -> Cont b) -> Cont a) -> Cont a
callCC = undefined  -- this definition seems impossible to implement

但是我在尝试定义和实现callCC时遇到了一个问题,如果我引用传统的定义,那么它应该是

代码语言:javascript
复制
callCC f = MkCont $ \c1 -> runCont (f (\x -> MkCont $ \c2 -> c1 x)) c1

但是上面的代码没有类型检查,所以我是犯了什么愚蠢的错误,还是不可能像这样定义Cont

PS:我不确定在我对Cont的定义中,上述类型的callCC是不是合适的,也许它需要一些调整。

EN

回答 1

Stack Overflow用户

发布于 2019-09-24 19:41:18

这个单体(转换器)也称为Codensityhttps://hackage.haskell.org/package/kan-extensions-5.2/docs/Control-Monad-Codensity.html

您实际上也没有实现reset,除了类型之外还有更多的东西。必须满足以下等式:

移位复位(

f >>= k) =复位(f (evalCont .k))

-- https://hackage.haskell.org/package/transformers-0.5.6.2/docs/Control-Monad-Trans-Cont.html#v:shift

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58077208

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档