Functional programming scala中处理状态的不变方法
我只是在学习Scala的同时开始我的FP之旅 现在需要在未过滤的web应用程序中维护Functional programming scala中处理状态的不变方法,functional-programming,state,scalability,scalaz,unfiltered,Functional Programming,State,Scalability,Scalaz,Unfiltered,我只是在学习Scala的同时开始我的FP之旅 现在需要在未过滤的web应用程序中维护列表[String]。当向端点发送POST请求时,应该从文件更新列表。当GET请求发送到同一端点时,将使用该列表 现在,我试图避免使用var来保存列表。我知道有时我们必须使用var,但我很好奇,有没有一种优雅的方法来处理这个问题。我试过使用scalaz.State迭代器和Steam。但是我被卡住了,因为我不知道如何将当前的不变状态传递给下一个请求。有什么建议吗 def update = State( l =>
列表[String]
。当向端点发送POST
请求时,应该从文件更新列表。当GET请求发送到同一端点时,将使用该列表
现在,我试图避免使用var
来保存列表。我知道有时我们必须使用var,但我很好奇,有没有一种优雅的方法来处理这个问题。我试过使用scalaz.State迭代器和Steam。但是我被卡住了,因为我不知道如何将当前的不变状态传递给下一个请求。有什么建议吗
def update = State( l => {
retrieve(filepath) match {
case Success(lines) => (lines.split("[,\n\r]").toVector.map (_.trim), true)
case Failure(_) => {
log.error(s"Cannot retrieve the file.")
(l, false)
}
}
})
def isContained(message: String) = State(l => (l, l.exists(message.contains)))
/* assume the following get or post method will be invoked when GET or POST request is sent to the endpoint */
def post() = update(Vector.empty) // how can I pass the updated state to the get method
def get(msg: String): Boolean = isContained(msg)(???)._2
然后,我不知道如何将当前状态作为输入传递给下一次就诊,而不使用
var
没有免费午餐。如果要避免易变性并避免将状态存储在某处,则需要使用返回值
State
只不过是一个函数a=>B
(出于某种目的,我将其简化了一点),其中a
是初始状态,B
是最终结果
因此,在您的情况下,模型将如下所示:
def post(newMessage: String, state: List[String]): List[String] = {
newMessage :: state
}
def get(msg: String, state: List[String]): Boolean = {
state.contains(msg)
}
正如您在这里看到的,您需要为每个post
和get
提供当前状态。POST只需从文件中添加一条新消息(将您的业务逻辑放在这里),并返回一个新状态。对于get
,您需要提供当前状态,以便能够检索到所需的内容。
您可以这样重写它:
def post(newMessage: String): List[String] ⇒ List[String] = state ⇒ {
newMessage :: state
}
def get(msg: String): List[String] ⇒ Boolean =
_.contains(msg)
请注意,post返回的正是A⇒ A
(其中A=List[String]
)
ScalaZState
为您提供了Monad,用于链接内部函数以便于理解,还提供了一些额外的便利(如map
,get
,put
等)。但本质上,基本模型是相同的
此代码更精确地表示状态
的功能:
type YourListState = List[String] ⇒ List[String]
def post(newMessage: String, state: YourListState): YourListState = li ⇒ {
newMessage :: state(li)
}
def get(msg: String, state: YourListState): List[String] ⇒ Boolean = {
state(_).contains(msg)
}
这允许您组合状态并提供初始值,并在需要时“运行”它,而不确定您是否真的需要它