Is this a suitable use of ContT?

I am working on a project that requires me to write a small interpreter. The instructions have a simple tree structure, and one of the commands has a termination effect. Therefore, in the example below, "baz" is never printed.

import Control.Monad.Cont

data Instruction = Print String | Halt | Block [Instruction]
    deriving (Eq, Show)

instructions =
  [ Print "foo"
  , Block
    [ Print "bar"
    , Halt
    ]
  , Print "baz"
  ]

main :: IO ()
main = runContT (callCC $ interpret instructions)
                (const $ pure ())

interpret []     k = pure ()
interpret (a:as) k = case a of
    Print str -> liftIO (putStrLn str) >> interpret as k
    Block ins -> interpret ins k       >> interpret as k
    Halt      -> k ()

This is the first time I've seen potential use for ContTin one of my projects. I was wondering if this is suitable for this, or if there is a simpler solution that I could ignore.

+6
source share
1 answer

Yes, it looks like an example of use for which it is suitable Control.Monad.Cont.

, , interpret , IO (), :

main :: IO ()
main = interpret instructions

interpret :: [Instruction] -> IO ()
interpret []     = pure ()
interpret (a:as) = case a of
    Print str -> putStrLn str >> interpret as
    Block ins -> interpret ins >> interpret as
    Halt      -> pure ()

foo bar baz . , . , callCC. (k ) , /.

, ContT , .

+7

All Articles