Created
August 21, 2024 21:28
-
-
Save sgf-dma/06ba1a9e99c995cd79cc226e8a575548 to your computer and use it in GitHub Desktop.
cps version of 'reverse' for comparison with Go version in revCps.go.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Control.Monad.Trans.Cont | |
import Data.Function | |
data R a = R (R a) | E a | |
-- This function is called from 'shift' and 'shift' returns immediately | |
-- (without calling further continuation) because result is already here - 'R' | |
-- value. Continuation 'k' will be called later, when evaluation of returned | |
-- 'R' value is forced in 'run'. | |
step :: a -> [a] -> ([a] -> R [a]) -> Cont (R [a]) (R [a]) | |
step x xs k = return $ R (k (x : xs)) | |
reverseCps :: [a] -> R [a] | |
reverseCps xs = flip runCont id -- Go: m(nil) | |
-- $ foldr (\x m zs -> shift (step x zs) >>= m) | |
$ foldr -- Go: for _, x := range xs | |
(\x m -> \zs -> m =<< (shift (step x zs))) -- Go: m = func (k Cont) Cont {..} | |
(return . E) -- Go: return nil, []int | |
xs | |
[] -- Initial value of reversed list, Go: Either 'nil' in 'return m(nil)' or '[]int{}' in following 'return nil, []int{}'. | |
-- 'rec' is anonymous recursion supplied by 'fix'. | |
run :: (R [a] -> [a]) -> R [a] -> [a] | |
run rec (R z) = rec z | |
run rec (E z) = z | |
main :: IO () | |
main = print | |
. fix run -- Go: for ; zs == nil; f, zs = f() | |
$ reverseCps [1..5] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment