在FP中处理POST的正确方法是什么?

Mal*_*lio 8 post functional-programming scala web-frameworks

我刚刚开始使用FP而且我正在使用Scala,这可能不是最好的方式,因为如果情况变得艰难,我总能回到命令式的风格.我只是不愿意.我有一个非常具体的问题,指出我对FP的理解有更广泛的空白.

当Web应用程序正在处理GET请求时,用户需要网站上已存在的信息.应用程序只需要以某种方式处理和格式化数据.FB的方式很清楚.

当Web应用程序正在处理POST请求时,用户希望更改站点上保存的信息.没错,信息通常不是在应用程序变量中保存,而是在数据库或平面文件中,但我仍然觉得我没有正确地使用 FP.

是否有处理FP语言中静态数据更新的模式?

我对此的模糊描述是应用程序交给请求和当时的站点状态.应用程序执行其操作并返回新的站点状态.如果自应用程序启动当前站点状态并没有改变,新状态成为当前状态,并答复将被发送回浏览器(这是我的Clojure的风格模糊图像); 如果当前状态已经改变(通过另一个线程,那么,其他事情发生了...

Lan*_*dei 6

在纯FP环境中处理此类问题的一种方法是像Haskell中的monad(例如IO和State),但是在Clean中有诸如"unique types"(只允许对值的一个引用)之类的替代方法.

没有太多神交这里:如果你有可变的状态,那么你就需要以某种方式限制访问它,在这种状态下的每一个变化的方式感知为结构的"新版本"从程序的其它部分.例如,您可以将Haskell的IO视为"世界其他地方",但附加了一种时钟.如果您对IO执行某些操作,则时钟会打勾,并且您再也看不到相同的IO.下次你触摸它时,它是另一个IO,另一个世界,你所做的一切都已经发生了.

在现实生活中,你可以"看到"电影中的"变化" - 这是必要的观点.但是如果你抓住这部电影,你会看到一串不可变的小图片,没有任何"改变"的痕迹 - 这就是FP视图.这两个视图在其自己的上下文中都是有效且"真实"的.

但是,如果你使用Scala,你可以拥有可变状态 - 这里没问题.Scala根本不需要任何特殊处理,使用它没有任何问题(虽然它被认为是"好的风格",以保持"不纯"的点尽可能小).


eph*_*ent -1

注意:我根本不了解 Scala,所以我只是猜测示例中的语法。

这是实现地图的一种实用方法:

val empty           = x =>                scala.None
def insert(k, v, m) = x => if k == x then scala.Some(v) else m(k)
def delete(k, m)    = x => if k == x then scala.None    else m(k)
def get(k, m)       = m(k)
Run Code Online (Sandbox Code Playgroud)

映射可以只是一个函数,而不是传统的数据结构。要从映射中添加或删除条目,需要将函数与现有映射组合起来以生成新映射。

我也喜欢这样思考网络应用程序。Web 应用程序将请求转换为事务。事务将一种状态转变为另一种状态,但它可以应用于当前状态,或某些过去的状态,或某些未知的未来状态。仅仅交易是没有用的;必须有某种东西对它们进行排序,一个接一个地应用它们。但请求处理程序根本不必考虑这一点。

作为示例,我们来看一下Happstack框架如何对状态进行建模。传入请求被路由到在 monad 内运行的处理程序。部分归功于一些TH魔法,该框架序列化了生成的节点并将其添加到不断增长的事务日志的尾部。要确定最新状态,只需单步浏览日志文件,按顺序应用事务即可。(Happstack 也可以编写“检查点”,但它们并不是操作所必需的。)