Skip to content

Instantly share code, notes, and snippets.

@jsoffer
Created October 2, 2009 22:21
Show Gist options
  • Save jsoffer/200198 to your computer and use it in GitHub Desktop.
Save jsoffer/200198 to your computer and use it in GitHub Desktop.
-- Forma directa de implementar una máquina de estado vía Control.Monad.State
-- Implementa acciones en secuencia; no espera caso final, ejecuta k veces la máquina
-- Modificado a partir de http://www.haskell.org/pipermail/beginners/2008-September/000275.html
module FibState where
import Control.Monad.State
import Control.Monad
-- ¿cual es el tipo de datos del estado?
data FibState = F { previous, current :: Integer }
-- Estado inicial
fibState0 = F {previous = 1, current = 0}
-- Parte del estado actual; 'current' es un accesor al tipo de dato
currentFib :: State FibState Integer
currentFib = gets current
-- La maquinita. Adquiere el estado, hace la operación y crea el nuevo estado.
nextFib :: State FibState (IO ())
nextFib = do
F p c <- get -- estado actual
let n = p+c
put (F c n) -- estado siguiente
-- return n -- salida, lo que se va a sacar y enlazar en una lista
return (putStrLn $ show n)
-- Va de un solo paso a una serie de k pasos
--getNFibs :: Int -> State FibState [Integer]
getNFibs :: Int -> State FibState [IO ()]
getNFibs k = replicateM k nextFib
-- Genera la sucesión. Notar que lo de 'fibState0' no se incluye; comienza a
-- partir del 'n = 0 + 1' que regresa el primer 'nextFib'.
--fibonacci :: Int -> [Integer]
fibonacci :: Int -> IO [()]
fibonacci k = sequence $ evalState (getNFibs k) fibState0
-- Así estaba en el original.
--main :: IO ()
--main = print $ evalState (liftM2 (:) currentFib (getNFibs 500) ) fibState0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment