![]() |
1
13
您当然可以实现这一点,并获得关于组件分离的非常强的静态保证。 最简单的说,你想要一个受限的io monad。使用类似于“污染”的技术,您可以创建一组提升到简单包装器中的io操作,然后使用模块系统隐藏类型的底层构造函数。 这样,您只能在cgi上下文中运行cgi代码,在db上下文中运行db代码。关于黑客攻击有很多例子。 另一种方法是为操作构造一个解释器,然后使用数据构造函数来描述您希望的每个基本操作。这些操作仍然应该形成一个monad,您可以使用do符号,但是您将构建一个描述要运行的操作的数据结构,然后通过解释器以受控方式执行。 在典型情况下,这可能会给您提供比所需更多的内省,但这种方法确实会让您在执行用户代码之前充分检查用户代码。 |
![]() |
2
5
我认为除了斯图尔特提到的两种方法之外还有第三种方法,这可能更简单:
其思想非常简单,就是为要分离的各种操作子集定义类型类,然后使用它们对函数进行参数化。即使您创建类实例的唯一具体monad是io,在任何monaddb上参数化的函数仍然只能使用monaddb操作(以及从它们构建的操作),因此您可以获得所需的结果。在io monad中的“可以做任何事情”函数中,可以无缝地使用monaddb和monadcgi操作,因为io是一个实例。 (当然,你 可以 如果需要,请定义其他实例。通过各种Monad变形金刚提升操作是很简单的,我认为实际上没有什么可以阻止您为Stewart没有提到的“包装器”和“解释器”Monad编写实例,从而组合这些方法——尽管我不确定是否有如果你愿意的话。) |
![]() |
3
4
谢谢你的提问! 我在一个客户机/服务器web框架上做了一些工作,该框架使用monad来区分不同的执行环境。显而易见的是 客户端 和 服务器端 ,但它也允许你写 两面 代码(可以在客户机和服务器上运行,因为它不包含任何特殊功能)以及 异步客户端 用于在客户机上编写非阻塞代码(本质上是客户机端的延续monad)。这听起来与您区分cgi代码和db代码的想法非常相关。 以下是有关我的项目的一些资源:
我认为这是一种有趣的方法,它可以为您提供关于代码的有趣保证。不过,还有一些棘手的问题。如果您有一个服务器端函数
如果有两个这样的函数,那么编写它们就不那么简单了。而不是写作
你可以用一些组合词来写同样的东西,但我的观点是构图不那么优雅。 |
![]() |
trpnd · 如何定义由两个任意单声道变压器组成的单声道变压器? 3 年前 |
![]() |
Fabus1184 · Haskell mapM_不打印 3 年前 |
![]() |
Gotthold · 基于范数约束向量的类型 3 年前 |
![]() |
jian · haskell将另一个函数用作输入参数 3 年前 |
![]() |
Jocafrei · 用Haskell函数实现最大公约数函数 6 年前 |