我正在为Haskell中的简单命令式语言编写编译器,输出Java字节码.我已经到了我发出字节码的抽象表示的地步.
在编写用于编译if语句的代码时遇到了一些麻烦.要实现if语句,我需要跳转到标签.因此,我需要为该标签生成一个名称,该名称必须是唯一的.
我的第一个想法是通过一些状态compileStatement,即
compileStatement :: Statement -> UniqueIDState -> [AbstractInstruction]
Run Code Online (Sandbox Code Playgroud)
当然,compilerStatement是递归的,所以使用这种方法需要我从递归调用中将唯一ID生成器的状态传递回upp:
compileStatement :: Statement -> UniqueIDState -> (UniqueIdState, [AbstractInstruction])
Run Code Online (Sandbox Code Playgroud)
这看起来有点笨拙,特别是如果我意识到我需要在将来携带更多状态; 有更优雅的方式吗?
可能重复:
在Haskell中创建唯一标签
我有一个数据类型Person和一些输入数据,我将从中创建人员.
我想让每个人都有自己的ID(假设整数[0 ..]).我可以通过递归来做到这一点,但是因为我在Haskell中这样做,所以我想了解monad.我想,State Monad可能是这项工作的最佳人选.
问题是,我并不是很了解很多东西:当我在monad中时(什么功能可以使用内部),我如何将它们连接在一起,如何使'tick'功能提前等等. .
所以我现在坚持这个:滴答功能可能有效,但我不知道如何使用它; 以及如何相继获得人才建设的价值.
import Control.Monad.State
data Person = Person {
id :: Int,
name :: String
} deriving Show
type MyState = Int
startState = 0
tick :: State MyState Int
tick = do
n <- get
put (n+1)
return n
names = ["Adam","Barney","Charlie"]
-- ??? -> persons = [Person 0 "Adam", Person 1 "Barney", Person 2 "Charlie"]
main = do
print $ evalState tick startState
-- ???
Run Code Online (Sandbox Code Playgroud)
编辑:使用Data.Unique或Data.Unique.Id会更容易吗?如何在我的情况下使用它?