用函数式语言推箱子
Posted Neuromancer
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用函数式语言推箱子相关的知识,希望对你有一定的参考价值。
最近花了两三个晚上照着CIS194的前三节课课件用Haskell写了一个简单的推箱子程序。
然而推箱子这种相当Stateful的应用拿函数式写还是非常麻烦的。幸好CodeWorld API把GUI和服务器等的底层都实现好了,不然也不可能两百多行就写完。
这里面要说我感受到的Haskell(主要是相对C++而言,毕竟别的我也没怎么深入用过)有什么好处?我来想着说一说吧。
模式匹配
有了模式匹配写状态转移相当方便。写起来行云流水,比层层嵌套的if-else简洁得多。也比C++中的switch语句功能强大许多。
代数数据类型
相比用C++中的Union/Enum,用代数数据类型来实现不同类型的组合相当自然,语法很简洁。比如界面的状态可以是“开始”或是某一个依据地图、箱子位置、人的位置确定的迷宫或是“结束”,就可以直接写成“type State = Start | State (Coord -> Tile) (List Coord) Coord | Finish”。用C++写的话就要冗长琐碎许多了。
高阶函数和类型参数
还有一个非常舒服的是高阶函数和类型参数的引入使得代码重构也非常方便。在写交互的时候,CodeWorld API提供了一个interactionOf函数。一开始设计的时候,并没有考虑到开始结束这些过程。在之后开始考虑加入开始页面时,直接在在原先的State类型上再套了一个代数数据类型(用代码说就是用SSState (= StartScreen | Running State)代替State)。利用原来的State相关的函数,我可以非常方便地在这基础上构建SSState相关的函数,不需要特别繁琐的全盘重构。虽然C++的多态、继承也可以做到这些,但要实现一个虚的基类,所有需要被某个函数调用的函数都需要继承这个基类,要是遇到菱形继承就又是一桩头疼事;Haskell相比较而言,耦合度低了很多。
这些“好用”应该还是有一些专业术语的,然而我现在学得不深,大家就意会一下吧XD
当然劣势也是有的,比如:1、慢:运行后有肉眼可见的延迟,尽管地图非常简单;2、代码可读性不高:由于函数式语言没什么顺序执行的概念,所以写的时候各种函数非常分散。
嗯,就胡诌这么多。
明天想想怎么把地图数据导入到程序中,搞定了就开始看monadic parser combinator了
= =
点击“阅读原文”查看github repo
以上是关于用函数式语言推箱子的主要内容,如果未能解决你的问题,请参考以下文章