/ / ¿Es este un uso apropiado de ContT? - Haskell, mónadas, continuaciones.

¿Es este un uso apropiado de ContT? - Haskell, mónadas, continuaciones.

Estoy trabajando en un proyecto que me obliga aEscribe un pequeño intérprete. Las instrucciones tienen una estructura de árbol simple y uno de los comandos tiene el efecto de detener la ejecución. Así que en el siguiente ejemplo, "baz" nunca se imprime.

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 ()

Esta es la primera vez que veo un uso potencial para ContT en uno de mis proyectos. Me preguntaba si este es un uso apropiado o si hay una solución más simple que podría estar pasando por alto.

Respuestas

7 para la respuesta № 1

Sí, este parece ser precisamente el tipo de caso de uso para el que Control.Monad.Cont es apropiado.

Es casi seguro que eres consciente de esto, pero para otros lectores, vale la pena explicarlo si escribiste interpret de modo que fuera una función de una lista de instrucciones a una IO () al igual que:

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 ()

entonces foo bar y baz Todos habrían impreso. Lo que necesitaba era un mecanismo de escape que le permitiera abortar todo el cálculo e inmediatamente devolver un valor. Esto es precisamente lo que callCC proporciona. Llamando a la computación nombrada (k en su código) le permite escapar de todo el cálculo, no solo de ese nivel / capa.

Muy bien, ha encontrado el caso de uso adecuado para ContT aquí, creo.