java parser_愿你走出半生,归来仍是Java Parser
几天前,我的一个朋友给了我一个Haskell问题Hey, MK,假设我有个BNF,并且我在Haskell中有个这个BNF的parser。
现在,我想给这个BNF改一行,有没有办法不用动这个BNF parser的代码(因为是其他人写的),而是对这parser进行扩展呢?
这问题挺有趣的,也不算难。
这问题说是extensibility problem,其实有两个地方需要扩展。
0:Parser需要用open recursion之类的方法扩展
1:Parse出来的ADT也需要可扩展性
后半个需求见多了,Final Tagless,DTALC,Tree that grow,Recursion scheme style fix。。。于是放下不表,我们来处理前一个。
前半个。。Haskell's Overlooked Object System就搞过,当然他们有点heavy weight,打算随手弄一个超级轻量级的:5行就够了,多一行是小莎莎。
Ready?
data Object x = MkObject (x -> x)
1。Inheritance is not subtyping式的Object=recursive type。为了简易性(反正也不需要多高的扩展性)就不model真。recursive type,而只有recursive dependency。
use :: Object x -> x
use (MkObject x) = let res = x res in res
2。3。最典型的tying the knot。其实就是fix了。
我们想想,这个x是什么variant的呢?covariant还是contravariant?
inherit :: (a -> b) -> (b -> a) -> Object a -> Object b
inherit ab ba (MkObject aa) = MkObject (ab . aa . ba)
既然是invariant,那fmap contramap都用不上,但invariant依然能有map:两边一起传进来就行了。4。5。
这就是一个prototype based oo system了。
接下来讲怎么用哈:
test :: Object (Int, Int)
test = MkObject $ \self -> (2, fst self + fst self)
这弄了个两个field的object,第零个field初始值为2(可能因为继承被override),第一个field为第零个field的值*2(不一定是3,如果任何field被override这个值都能改)。use test应该是(2, 4)。
inheritTest :: Object ((Int, Int), Int)
inheritTest = inherit (\(l, r) -> ((l + 1, r + 2), r + 1)) fst test
这里继承了上面的Object,override了l(l + 1是super + 1),r被override到super + 2,加了个新的field,值是r+1。use inheritTest应该是((3, 8), 7)。记着传进来的参数不是self而是super就很好理解了。
好,open recursion搞好了,剩下的就是标准的final tagless了,体力活,没啥意思
class AST repr where
lit :: Int -> repr
plus :: repr -> repr -> repr
class Var repr where
var :: String -> repr
type WholeParser repr = Parser repr
type LitParser repr = Parser repr
type PlusParser repr = Parser repr
intP :: Parser Int
intP = read many1 digit
stringP :: Parser String
stringP = many1 letter
type OriginalParser repr = ((LitParser repr, PlusParser repr), WholeParser repr)
originalParser :: AST repr => Object (OriginalParser repr)
originalParser = MkObject $ \(~(_, p)) -> let
litP = lit intP
plusP = between (char '(') (char ')') (do {l
wholeP = litP plusP in
((litP, plusP), wholeP)
type VarParser repr = Parser repr
extendedParser :: (AST repr, Var repr) => Object (VarParser repr, OriginalParser repr)
extendedParser = inherit extend snd originalParser
where
extend ~((litP, plusP), wholeP) = let
varP = var stringP in
(varP, ((litP, plusP), varP wholeP))
instance AST String where
lit = show
plus x y = "(" ++ x ++ " " ++ "+" ++ " " ++ y ++ ")"
instance Var String where
var x = x
大功告成。
Q:封装呢?
A:Abstract Type is Existential Type
Q:这是prototype based的,class怎么办?
A:A Theory Of Object里面讲过怎么用prototype来做class
Q:多继承呢?
A:给定Object a,Object b,可以组合出Object (a, b),要菱形继承自己手动再inherit一下就好
Q:Subtyping?
A:Typeclass。
如果大家感兴趣,请评论下,我可以再写个blog把这些功能补完。
java parser_愿你走出半生,归来仍是Java Parser相关推荐
- 愿你走出半生 归来仍是少年
作者:碎瓦 链接:https://www.zhihu.com/question/57671944/answer/200362753 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商业转载 ...
- java中parser_愿你走出半生,归来仍是Java Parser
几天前,我的一个朋友给了我一个Haskell问题 Hey, MK,假设我有个BNF,并且我在Haskell中有个这个BNF的parser. 现在,我想给这个BNF改一行,有没有办法不用动这个BNF p ...
- 给你的杭州旅游攻略-愿你走出半生,归来仍是姑娘
给你的杭州旅游攻略 -- 愿你走出半生,归来仍是姑娘 来杭州玩,西湖不用说,你肯定要的去啦.但是周末和节假日,不懂的人玩的地方都是人山人海.所以为了避免看人头呢,你可以到人少的景点,比如: 首先推荐柳 ...
- Cocos2dx游戏教程(十五):“见缝插针”,愿你走出半生,归来仍是少年
从决定写这个教程到第一个有戏教程结束也经历了好长时间,有的地方可能写的不好,也请大家多多包涵.决定写这个教程也是对自己学习的一个总结吧,写教程的过程也是自己学的过程. 一个小游戏所涉及到的知识点毕竟不 ...
- 愿你走出半生,归来仍是少年
不知不觉已经走到了现在 这半年学习了java,做了一个官网.做了大米互助的第一版,目前小有改头换面之式的第二版也在筹划之中:感谢云姐.坤哥的信任,保证完成任务:筹划的过程中我们有一些因为理解不同,进度 ...
- 皓月天边,半步青莲。愿你把酒持剑,归来仍是少年。
我还是像从前一样,冷漠不减,温柔用不上,狠心过了头. 多一点自知之明,少一点自作多情. 无法知道余生还要渡过多少不能被分担的漫漫长夜,无法知道我在那些漫漫长夜之后的黎明醒来想起这一段往事来,会是怎样的 ...
- Queue:愿你历尽千帆,归来仍是少年!
成长的路上必然经历很多风雨 相信自己终有属于你的盛举 别因为磨难 停住你的脚步 坚持住 就会拥有属于你的蓝图 ---<少年> 1. Queue 特点 队列是一种特殊的线性表,是一种先进先出 ...
- 《愿你历尽千帆,归来仍是少年》-曾锴
当时怀着好奇的心情买了这本书,读了这本书,最大的收获是认识了自己求学在外的意义,了解了作者在国外生活的经历,那是怀念家的感觉,求学不易,读书的用途.愿我们有缘今生,不忘初心,不负光阴,活出自我,终得精 ...
- java迷宫算法_Java 算法 走出迷宫!
前几天参加字节跳动招聘的笔试,遇到了一个走迷宫的题目(笔试题目,就不挂原图了),当时没有做出来,今天周末,上午总结了一下,来说一说这个迷宫到底怎么走 这篇文章将会分为三个部分,分别是:深度优先算法:获 ...
- java版DVD影碟片出租赁系统C/S模式 java电影购票系统课程设计
系统采用c/s架构,当然,你可以服务端.客户端都在同一台电脑上运行: 也可以在同一局域网内服务端.客户端在其它不同电脑上运行: 如果你有云服务器,可将Service端代码部署至云服务器上,客户端在任何 ...
最新文章
- 《深入理解计算机系统》学习心得二:关于show-bytes的 学习
- 知识图谱从哪儿来?实体关系抽取的现状和未来
- linux shell /dev/tcp/${HOST}/${PORT} 简介
- android检查usb广播,Android 检测USB 音频设备
- mysql实现查询最近7天的数据
- Leetcode 剑指 Offer 40. 最小的k个数 (每日一题 20210825)
- 记录 FreeBSD
- LeetCode 644. 最大平均子段和 II(二分查找)*
- 企业实战(Jenkins+GitLab+SonarQube)_07_Jenkins 安全设置
- Django框架——HttpRequest对象
- 北大朱占星:顶级会议疯狂投稿下的AI现状 | 专栏
- zynq中interrupts的学习笔记(一)
- 梯度下降与支持向量机
- 优化广域网带宽,让应用加速
- Kinect体感机器人(三)—— 空间向量法计算关节角度
- Mybatis学习-动态SQL
- 如何去掉 APFS 宗卷 • APFS(加密)的加密功能
- 使用循环神经网络训练语言模型(从简单起手、歌词生成器,爬虫+GRU循环网络)
- 疯狂Python讲义学习笔记(含习题)之 类和对象
- 人民日报撰文—— 张钹:中国人工智能奠基者
热门文章
- 小心! Java三目运算符
- 最新!Win10安装Mysql 5.7.22免安装版的图文教程(路过太多的坑了)
- 【学习笔记】黑马程序员Java课程学习笔记(更新至第12章---集合)
- MySQL 网站上的 GA 是什么意思?
- 获取图片中指定像素点的灰度值并画图显示
- “男朋友送了我一瓶才100多块的香水”
- python实现程序自动运行的库_python tkiner实现自动打包程序
- fcpx怎么合成延时摄影_简单易学的延时摄影合成教程
- 【主动学习 03】Active Self-Paced Learning for Cost-Effective and Progressive Face Identification (PAMI‘18)
- 不想安装环境,我如何与前端工程师远程协作开发?