haskell - 使用 Haskell 的类型系统来强制模块化

标签 haskell types type-systems

我正在考虑使用 Haskell 的类型系统在程序中强制执行模块化的方法。例如,如果我有一个 Web 应用程序,我很好奇是否有办法将所有数据库代码与 CGI 代码、文件系统代码与纯代码分开。

例如,我正在设想一个 DB monad,所以我可以编写如下函数:

countOfUsers :: DB Int
countOfUsers = select "count(*) from users"

我希望不可能使用 DB monad 支持的副作用以外的副作用。我正在描绘一个更高级别的 monad,它仅限于直接 URL 处理程序,并且能够组合对 DB monad 和 IO monad 的调用。

这可能吗?这是明智的吗?

更新 :我最终用 Scala 而不是 Haskell 实现了这一点:http://moreindirection.blogspot.com/2011/08/implicit-environment-pattern.html

最佳答案

I am picturing a higher-level monad that would be limited to direct URL handlers and would be able to compose calls to the DB monad and the IO monad.



您当然可以实现这一点,并获得关于组件分离的非常强大的静态保证。

最简单的,你想要一个受限的 IO monad。使用类似“污染”的技术,您可以创建一组提升到简单包装器的 IO 操作,然后使用模块系统隐藏类型的底层构造函数。

这样,您将只能在 CGI 上下文中运行 CGI 代码,而在 DB 上下文中运行 DB 代码。关于 Hackage 的例子很多。

另一种方法是为 Action 构造一个解释器,然后使用数据构造函数来描述您希望的每个原始操作。这些操作仍应形成一个 monad,并且您可以使用 do-notation,但您将构建一个描述要运行的操作的数据结构,然后您可以通过解释器以受控方式执行它。

在典型情况下,这可能会为您提供比您需要的更多的内省(introspection),但该方法确实使您能够在执行用户代码之前充分检查它。

关于haskell - 使用 Haskell 的类型系统来强制模块化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2383778/

相关文章:

haskell - 通过蕴涵削弱黑胶唱片的 RecAll 约束

scala - 从字符串文字推断 Spark DataType

jquery - 错误 : Property 'draggable' does not exist on type 'JQuery<HTMLElement>'

Scala - 在编译时强制执行 Vector 的大小

haskell - 除 * 之外的 child 的字符串表示形式

haskell - Typo(?) ("composition") 七周内七种语言 - Haskell 部分

haskell - 将 optparse-applicative 与多个子命令和全局选项一起使用

c++ - 超出芯片组允许的最大数据类型。 C++

haskell - Haskell 如何对无限递归值进行类型检查?

c# - 为什么我不能对结构使用 as 关键字?