haskell / haskell/mtl

MonadReader instance for ContT has bad semantics

未关闭
#83 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
主要语言
Haskell
星标
401
派生
72
PR 合并指标
30 天内没有已合并 PR

描述

We'd expect `local id == id`, but this isn't true for `ContT`.

Let:
```haskell
localTheCont :: MonadReader Int m => ContT r m ()
localTheCont = ContT $ \c -> local (+1) (c ())

test1 :: MonadReader Int m => ContT r m Int
test1 = localTheCont >> ask

test2 :: MonadReader Int m => ContT r m Int
test2 = local id localTheCont >> ask
```
then
```haskell
runReader (evalContT test1) 1 == 2
runReader (evalContT test2) 1 == 1
```

Breaking apart the instance reveals what goes wrong:
```haskell
local id localTheCont
= ContC $ \c ->
i <- ask
local id $ runContC localTheCont (local (const i) . c)
= ContC $ \c ->
i <- ask
local id $ local (+1) ((local (const i) . c) ())
= ContC $ \c ->
i <- ask
local (const i . (+1) . id) (c ())
= ContC $ \c ->
i <- ask
local (const i) (c ())
```
Removing the instance would undoubtedly cause too much breakage, but perhaps a warning in the docs is warranted.

贡献指南

这个仓库没有索引到贡献指南

评估

这个 Issue 还没有评估数据。

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。