Lambda和策略模式 这是「从函数式角度看设计模式」的第一篇。目的是从和OOP不同的角度重新审视设计模式。 第一篇就从lambda说起了,因为这是函数式编程里面最常见的概念。在设计模式里,这个概念一般叫做「策略模式」。 按照定义,「策略模式是一种行为设计模式, 它能让你定义一系列算法, 并将每种算法分别放入独立的类中, 以使算法的对象能够相互替换」。简而言之,就是不把算法写死,而是在运行时可以按需切换。一般来说,OOP 2022-09-25 程序设计杂谈 #设计模式 #函数式编程
小结和之后打算做的一些事情 在上次笔记后又过了一段时间,在 parser 方面并没有太多的进展。倒是在反复测试后发现或许 MonadError、MonadState 和 catchError 的办法能够提供我想要的组合子的语义。也为此做了一些简单的测试。 当然了,也有缺点:在有些语法分支上,是不得不使用 try 组合子的。而一旦启用了这个组合子,就又会不得不处理回溯的问题。 不过相比另一个问题,这个问题算是比较好解决的了。那 2022-05-26 水 #破事水
从零开始的编译器前端之Parser与Lexer的一些其他的细节(待更新) 这篇文章讲一些相比前几篇比较无关紧要的细节,算是写Parser/Lexer时候的踩坑的记录吧。之后遇到了更多的坑,也会写在这篇文章里。 主要的一个大坑就是例如val a = sum<int>(3 + 4) 或者val b = foo<int, char>(...) 这里面用尖括号包起来的泛型类型标记,起初试验了许多不同的办法,也一度想过放弃,不过最后还是获得了相对比较令人满 2022-04-16 笔记 #破事水
从零开始的编译器前端之LL(1)语法与Parser Combinator 写完了Lexer(其实没有),就可以开始准备写Parser了。为了方便调试,首先用ANTLR的语法来写,这样就可以在IDEA里面使用插件来实时调试语法的正确性。 不过,ANTLR的语法属于EBNF等价的,需要首先转化为BNF语法,这样才可以进行消除左递归和提取左公因子等操作转化为LL(1)文法。 之所以要转化为LL(1)的原因,还是跟Parser Combinator的缺陷有关。实际上,作为一种递 2022-04-05 笔记 #Haskell #编译器
从零开始的编译器前端之Lexer 这是第三篇文章,打算简单介绍一下Lexer的概念。跟之前的篇幅不同,这部分内容就完全是自己瞎弄出来的了。 不保证正确性但是应该也可以作为一种思路吧。 之前也提到过用token组合子来在Parsing过程中进行Tokenization的操作,如果遇到了注释,就会出现问题。像是//这样的注释,会从注释的起始位置一直延伸到行末,又比如/* ... */这样的注释需要一直延伸到*/为止,但是针对单个字符 2022-03-13 笔记 #Haskell #编译器
换了一个主题 之前一直在用的Diaspora主题,其实算是随便找了个主题,还是有许多地方感觉受到了限制,比如说不支持页尾脚注,也没有自定义页面样式或者是友情页面模板这样的事情。 这次就换成了Fluid,总体来说可以保持和之前一致的风格,页尾脚注和友情页面都有了,还是挺满意的。 这个主题还支持LaTeX和Mermaid,不过虽然现在暂时用不到就是了。 主题是在这里找到的:https://github.com/fl 2022-02-23 水 #破事水
从零开始的编译器前端之Monadic Parsing 这是第二篇文章。这篇文章试图介绍一下Monadic Parsing的基本概念。 主要的内容来自于Programming in Haskell,虽然也加上了一些自己的个人理解。 提到编译器,就不可避免的要提到Parser了。那么,什么是Parser呢? 抽象而言,Parser是一种输入字符串输出树状的数据结构的程序。一段含有特定的结构的文本(某个语言里面的程序的代码)被解析后生成对应的抽象语法树( 2022-02-13 笔记 #Haskell #编译器 #Monad
从零开始的编译器前端之前置知识点 可能会是一个关于如何用monadic parsing来手写编译器的系列,来记录自己做实现的时候遇到的坑和一些经验。 第一篇文章会简单介绍一下一些基础设定。 首先是Monad。 众所周知,自函子范畴上的……(拖走暴打 好吧,这里不讨论学术上的定义,只试着以纯粹的使用者的角度从OO的视角出发去理解一下Monad,当然还有Functor,Applicative和Alternative这些typeclas 2022-02-10 笔记 #Haskell #FP
重新开坑coq兼复盘之前的三个未解之谜 其实在挺久以前有试过啃 coq 来着,虽然后来就放弃了(大概停留在 Logic 和 Tactics 两章之间)。 这次重新开坑倒是还算顺利,可能因为这之后在fp方面有了一些积累,对于命题的归纳证明也有了更直观的认知。借着万圣节放假的时候半个星期左右啃到了 Logic 一章。 当然这里面也有一部分原因是因为有参考到之前的题解,well,not really,一方面因为有许多题目自己直接 intros 2021-11-07 水 #coq
用无限序列来生成Fibonacci(的实现) 之前在学Haskell的时候碰到过一段这样的实现: 1fibs = 0 : 1 : zipWith (+) fibs (tail fibs) 感觉很优雅,主要是因为用到无限序列自己来定义自己,然后就等于把 fib 的定义直译一遍,就得到了对应的函数了( 然后就一直念念不忘是不是可以在命令式里面搞这个。 现在既然有了 Lazy 和 Stream 这两个工具(这里的 Stream 只是一个可以无穷延伸 2021-08-23 笔记 #Kotlin #破事水 #FP