Можно ли упростить определение Cont с помощью RankNTypes? - PullRequest
3 голосов
/ 24 сентября 2019

Я читаю эту реализацию из Continuation в Haskell, и считаю, что большую часть времени это сложно, r не так важен, поэтому мы предоставляем reset, чтобы было легкозаменен.

Так что я думаю, что переменную типа r в Cont r a не нужно подвергать воздействию, может быть, мы можем просто использовать 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, может быть, нужно немного отрегулировать.

1 Ответ

0 голосов
/ 24 сентября 2019

Эта монада (преобразователь) также называется Codensity: 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

...