几天前,我的一个朋友给了我一个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相关推荐

  1. 愿你走出半生 归来仍是少年

    作者:碎瓦 链接:https://www.zhihu.com/question/57671944/answer/200362753 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商业转载 ...

  2. java中parser_愿你走出半生,归来仍是Java Parser

    几天前,我的一个朋友给了我一个Haskell问题 Hey, MK,假设我有个BNF,并且我在Haskell中有个这个BNF的parser. 现在,我想给这个BNF改一行,有没有办法不用动这个BNF p ...

  3. 给你的杭州旅游攻略-愿你走出半生,归来仍是姑娘

    给你的杭州旅游攻略 -- 愿你走出半生,归来仍是姑娘 来杭州玩,西湖不用说,你肯定要的去啦.但是周末和节假日,不懂的人玩的地方都是人山人海.所以为了避免看人头呢,你可以到人少的景点,比如: 首先推荐柳 ...

  4. Cocos2dx游戏教程(十五):“见缝插针”,愿你走出半生,归来仍是少年

    从决定写这个教程到第一个有戏教程结束也经历了好长时间,有的地方可能写的不好,也请大家多多包涵.决定写这个教程也是对自己学习的一个总结吧,写教程的过程也是自己学的过程. 一个小游戏所涉及到的知识点毕竟不 ...

  5. 愿你走出半生,归来仍是少年

    不知不觉已经走到了现在 这半年学习了java,做了一个官网.做了大米互助的第一版,目前小有改头换面之式的第二版也在筹划之中:感谢云姐.坤哥的信任,保证完成任务:筹划的过程中我们有一些因为理解不同,进度 ...

  6. 皓月天边,半步青莲。愿你把酒持剑,归来仍是少年。

    我还是像从前一样,冷漠不减,温柔用不上,狠心过了头. 多一点自知之明,少一点自作多情. 无法知道余生还要渡过多少不能被分担的漫漫长夜,无法知道我在那些漫漫长夜之后的黎明醒来想起这一段往事来,会是怎样的 ...

  7. Queue:愿你历尽千帆,归来仍是少年!

    成长的路上必然经历很多风雨 相信自己终有属于你的盛举 别因为磨难 停住你的脚步 坚持住 就会拥有属于你的蓝图 ---<少年> 1. Queue 特点 队列是一种特殊的线性表,是一种先进先出 ...

  8. 《愿你历尽千帆,归来仍是少年》-曾锴

    当时怀着好奇的心情买了这本书,读了这本书,最大的收获是认识了自己求学在外的意义,了解了作者在国外生活的经历,那是怀念家的感觉,求学不易,读书的用途.愿我们有缘今生,不忘初心,不负光阴,活出自我,终得精 ...

  9. java迷宫算法_Java 算法 走出迷宫!

    前几天参加字节跳动招聘的笔试,遇到了一个走迷宫的题目(笔试题目,就不挂原图了),当时没有做出来,今天周末,上午总结了一下,来说一说这个迷宫到底怎么走 这篇文章将会分为三个部分,分别是:深度优先算法:获 ...

  10. java版DVD影碟片出租赁系统C/S模式 java电影购票系统课程设计

    系统采用c/s架构,当然,你可以服务端.客户端都在同一台电脑上运行: 也可以在同一局域网内服务端.客户端在其它不同电脑上运行: 如果你有云服务器,可将Service端代码部署至云服务器上,客户端在任何 ...

最新文章

  1. 《深入理解计算机系统》学习心得二:关于show-bytes的 学习
  2. 知识图谱从哪儿来?实体关系抽取的现状和未来
  3. linux shell /dev/tcp/${HOST}/${PORT} 简介
  4. android检查usb广播,Android 检测USB 音频设备
  5. mysql实现查询最近7天的数据
  6. Leetcode 剑指 Offer 40. 最小的k个数 (每日一题 20210825)
  7. 记录 FreeBSD
  8. LeetCode 644. 最大平均子段和 II(二分查找)*
  9. 企业实战(Jenkins+GitLab+SonarQube)_07_Jenkins 安全设置
  10. Django框架——HttpRequest对象
  11. 北大朱占星:顶级会议疯狂投稿下的AI现状 | 专栏
  12. zynq中interrupts的学习笔记(一)
  13. 梯度下降与支持向量机
  14. 优化广域网带宽,让应用加速
  15. Kinect体感机器人(三)—— 空间向量法计算关节角度
  16. Mybatis学习-动态SQL
  17. 如何去掉 APFS 宗卷 • APFS(加密)的加密功能
  18. 使用循环神经网络训练语言模型(从简单起手、歌词生成器,爬虫+GRU循环网络)
  19. 疯狂Python讲义学习笔记(含习题)之 类和对象
  20. 人民日报撰文—— 张钹:中国人工智能奠基者

热门文章

  1. 小心! Java三目运算符
  2. 最新!Win10安装Mysql 5.7.22免安装版的图文教程(路过太多的坑了)
  3. 【学习笔记】黑马程序员Java课程学习笔记(更新至第12章---集合)
  4. MySQL 网站上的 GA 是什么意思?
  5. 获取图片中指定像素点的灰度值并画图显示
  6. “男朋友送了我一瓶才100多块的香水”
  7. python实现程序自动运行的库_python tkiner实现自动打包程序
  8. fcpx怎么合成延时摄影_简单易学的延时摄影合成教程
  9. 【主动学习 03】Active Self-Paced Learning for Cost-Effective and Progressive Face Identification (PAMI‘18)
  10. 不想安装环境,我如何与前端工程师远程协作开发?