Monad - A functional design pattern 今年学校课程里有一门课,大概要求选一门技术来介绍一下。考虑到我的编程偏好,我觉得介绍一下函数式编程的概念比一些很具体的厂商产品更有趣吧。所以就选了Monad。 想想也许适合水一篇文章,毕竟一般来说,接触函数式编程的人最终都要写一篇自己的Monad介绍文章(雾 这篇文章不是用来手把手教怎么入门Monad的,毕竟课程要求也不是这个,所以就是简单的「引子 - 正式介绍 - 用处和优势 - 案例 - 小结 2023-02-20 笔记 #函数式编程 #PLT
高阶函数和模版方法模式 这是「从函数式角度看设计模式」的第三篇。目的是从和OOP不同的角度重新审视设计模式。 实际上感觉都没什么好写的? 这是「模版方法模式」的定义和实现方法: 模板方法模式是一种行为设计模式, 它在超类中定义了一个算法的框架, 允许子类在不修改结构的情况下重写算法的特定步骤。 模板方法模式建议将算法分解为一系列步骤, 然后将这些步骤改写为方法, 最后在 “模板方法” 中依次调用这些方法。 步骤可以 2022-12-04 程序设计杂谈 #设计模式 #函数式编程
使用std::move和std::optional来更清晰地处理错误 在这个实习里也用到了基于C++的私有框架。这个框架虽说是基于C++17的,但是错误处理用的是错误码和参数位置返回出去的做法。可能和框架需要接入gRPC有关。 自己这边需要用框架来做一些简易的操作,实现一个自己的proxy服务器,也就想到了用std::optional来重新处理一下这个错误流程的想法了。 大概的思路是,因为自己写的方法会被框架托管,所以自己实现的每个方法都返回一个optional的值 2022-11-06 实习回顾 #C++
模式匹配,观察者模式和GADT 这是「从函数式角度看设计模式」的第二篇。目的是从和OOP不同的角度重新审视设计模式。 这里讨论的是观察者模式,和它在函数式语言里的等价品,模式匹配(Pattern Matching)。最后也会讨论到GADT(广义代数数据类型)。 Java的模式匹配 考虑一个可以容纳各种数据类型的列表,这里用的是Java语言。 123456public record Empty() {}var 2022-11-02 程序设计杂谈 #设计模式 #函数式编程 #PLT
UnityWebRequest的一个小坑 最近在实习,主要的内容是Unity(WebGL),需求是能够从服务器(Proxy)获取数据后展示出来,应该是个蛮简单的任务吧。 Unity提供了一个叫UnityWebRequest的工具类,封装了常用的网络方法。按理来说使用Get方法就能够很容易得到结果了,但是官网没有怎么await长时间请求的案例,网上抄来的其他代码也不管用。 后来发现问题出在不应该用下载过程中的UnityWebRequest. 2022-10-21 实习回顾 #Unity #协程
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 #编译器