Lazify状态机
我是Haskell的初学者,我正在尝试写一台懒惰的Lexer状态机。
我有这个代码,确定不是懒惰的代码。因此,我应该用什么样的库或模式来懒惰的此代码?
module Main where
import Control.Monad.State.Lazy
import Data.Sequence (Seq (..))
import qualified Data.Sequence as Seq
data Suppe = A | B Integer
data StateBase = StateBase String (Seq Suppe)
newtype StateFn = StateFn (StateBase -> (Maybe StateFn, StateBase))
type StateMachine = (Maybe StateFn, StateBase)
next :: StateMachine -> StateMachine
next (Just (StateFn f), x) = f x
next (Nothing, x) = (Nothing, x)
run :: String -> Seq Lexeme
run input = evalState go (Just startStateFn, startState)
where
startState = StateBase input Seq.empty
startStateFn = FnA
go :: State StateMachine (Seq Lexeme)
go = get >>= \stateMachine -> let newStateMachine = next stateMachine
in
case fst newStateMachine of
(Just _) -> put newStateMachine >> go
Nothing -> return $ getSeq $ snd newStateMachine
getSeq :: StateBase -> Seq Suppe
getSeq (StateBase _ seq) = seq
fnA :: StateFn
fnA = undefined
fnB :: StateFn
fnB = undefined
main = undefined
我正在使用容器 ^> = 0.6.0.1,mtl ^> = 2.2
I am beginner to Haskell and I am trying to write a Lexer State Machine that is Lazy.
I have this code that definitive is no lazy code. Thus what kind of library or pattern should I use to lazy-fy this code?
module Main where
import Control.Monad.State.Lazy
import Data.Sequence (Seq (..))
import qualified Data.Sequence as Seq
data Suppe = A | B Integer
data StateBase = StateBase String (Seq Suppe)
newtype StateFn = StateFn (StateBase -> (Maybe StateFn, StateBase))
type StateMachine = (Maybe StateFn, StateBase)
next :: StateMachine -> StateMachine
next (Just (StateFn f), x) = f x
next (Nothing, x) = (Nothing, x)
run :: String -> Seq Lexeme
run input = evalState go (Just startStateFn, startState)
where
startState = StateBase input Seq.empty
startStateFn = FnA
go :: State StateMachine (Seq Lexeme)
go = get >>= \stateMachine -> let newStateMachine = next stateMachine
in
case fst newStateMachine of
(Just _) -> put newStateMachine >> go
Nothing -> return $ getSeq $ snd newStateMachine
getSeq :: StateBase -> Seq Suppe
getSeq (StateBase _ seq) = seq
fnA :: StateFn
fnA = undefined
fnB :: StateFn
fnB = undefined
main = undefined
I am using containers ^>= 0.6.0.1, mtl ^>= 2.2
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
对我来说,看来您周围有太多的机器,这只是使事情混乱,使它难以看到懒惰在哪里丢失。您是否尝试过仅使用Direct Style编程?这样的事情:
我猜想这比
fna
和fnb
在您的设置中的实现要短(或仅可忽略的),同时清晰且非常明显地懒惰。To me, it looks like you have way too much machinery lying around, and it's just cluttering things up and making it too hard to see where laziness is being lost. Have you tried just using direct-style programming? Something like this:
I would guess this is shorter (or only negligibly longer) than implementations of
fnA
andfnB
in your setting, while being clear and quite visibly lazy.