haskell - 如何干净地定义包含具有公共(public)变量参数的函数的 Haskell 模块?

标签 haskell xml-rpc

我正在尝试编写一个 Haskell 模块,该模块使用库 haxr 为远程 XML-RPC API 定义函数。 .以下是 haxr 的文档建议您定义调用 examples.add 的 Haskell 函数的方式。在服务器上 url :

add :: String -> Int -> Int -> IO Int
add url = remote url "examples.add"

像这样调用:
server = "http://localhost/~bjorn/cgi-bin/simple_server"
add server x y

如果我有一个或两个 XML-RPC 方法,这对我来说似乎没问题(那时我不需要单独的模块)。但是,server 的重复在代码中是一个问题,因为我有接近 100 个函数。我无法定义 server在模块中,像这样:
someRemote :: Remote
someRemote = remote "http://example.com/XMLRPC"

add :: Int -> Int -> IO Int
add = someRemote "examples.add"

因为如果要灵活地使用它的代码,就不能对 URL 进行硬编码。我也无法定义 someRemote作为函数的参数,因为它具有相同的重复问题。

Haxr's examples没有提供有关如何解决此问题的线索。

我通常用命令式 OOP 语言(即 Java、Python)编写程序。如果我使用这些语言,我将定义一个带有构造函数的类,该构造函数采用 server ,以及所有使用对象实例的函数server变量,而不是询问调用代码。

我在 Haskell 中寻找了与此等效的内容,但我似乎不知道找到它的正确关键字。类型类似乎不是答案。我可以编写一个返回部分应用函数的高阶函数,但解包这些函数会更难看。

最佳答案

我不太确定“服务器重复”实际上是不是很糟糕。当然,您永远不应该复制冗长的文字,但是对于不会使代码困惑且易于替换的单个变量名,这应该不是什么大问题。

但是当然,您可以通过将共享变量附加到您正在使用的 monad 来轻松避免这种重复,类似于您将其附加到 OO 类对象的方式。这叫读者。

import Control.Monad.Trans.Reader
type RemoteIO = ReaderT String IO  -- or perhaps `ReaderT Remote IO`

add :: Int -> Int -> RemoteIO Int
add x y = do
   url <- ask
   lift $ remote url "examples.add" x y

关于haskell - 如何干净地定义包含具有公共(public)变量参数的函数的 Haskell 模块?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25326264/

相关文章:

Haskell 不可变数据

haskell - 具有惰性评估和内存消耗的蛮力

haskell - `EitherT` 的 Applicative 实例在哪里定义?

php - 使用 XML-RPC 登录 OpenERP

python - python中的xmlrpc客户端调用不返回

haskell - 如何使用高阶函数将 Haskell 中的两个列表交错在一行中

haskell - 循环列表中 where 子句的计算

python - 在 python-wordpress-xmlrpc 请求上设置自定义 header

用于 XML-RPC 的 C++ 库

odoo - 如何追溯添加外部 ID?