gpt4 book ai didi

haskell - 是否可以用 RankNTypes 来简化 Cont 的定义?

转载 作者:行者123 更新时间:2023-12-02 16:33:24 24 4
gpt4 key购买 nike

我正在阅读this implementation Haskell 中的 Continuation,感觉比较棘手,很多时候,r 并不是那么重要,所以我们提供了reset,方便被替换。

所以我认为Cont r a中的r类型变量没有必要暴露,也许我们可以使用forall r来隐藏r 完全位于 Cont 的定义内,所以以下是我的尝试:

{-# 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时遇到了问题,如果我引用传统的定义,那么它应该是

callCC f = MkCont $ \c1 -> runCont (f (\x -> MkCont $ \c2 -> c1 x)) c1

但是上面的代码没有进行类型检查,所以我是否犯了一些愚蠢的错误,或者不可能像这样定义Cont

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

最佳答案

这个单子(monad)(变压器)也称为Co密度:https://hackage.haskell.org/package/kan-extensions-5.2/docs/Control-Monad-Codensity.html

<小时/>

您还没有真正实现reset,它的内容不仅仅是类型。必须满足以下等式:

reset (shift f >>= k) = reset (f (evalCont . k))

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

关于haskell - 是否可以用 RankNTypes 来简化 Cont 的定义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58077208/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com