Edwin C. Brady撰写的关于Idris影响的"使用代数效应和依赖类型进行编程和推理"的论文包含(未引用的)声明:
尽管[效果和单子变换器]在功率上并不相同 - monad和monad变换器可以表达更多概念 - 但是捕获了许多常见的有效计算.
哪些例子可以通过monad变换器建模而不是效果?
所以我做到了......
{-# LANGUAGE Rank2Types, GADTs #-}
type Record fields = forall t. fields t -> t
data PersonField t where
Name :: PersonField String
Age :: PersonField Int
type Person = Record PersonField
Run Code Online (Sandbox Code Playgroud)
然后......
nigel :: Person
nigel Name = "Nigel"
nigel Age = 39
Run Code Online (Sandbox Code Playgroud)
这一切似乎都按预期工作.
我正在努力的是如何在let绑定中定义Person值.例如,这不起作用:
abigail :: Person
abigail = let x Name = "Abigail"
x Age = 27
in x
Run Code Online (Sandbox Code Playgroud)
给我:
无法将预期类型`t1'与实际类型匹配`[Char]'`t1'是不可触及的...
有没有办法让这个工作在let绑定中?
C中一个相当普遍的习惯用于采用多态闭包的函数将其表示为两个参数,一个函数指针和一个void指针(它作为函数指针的一个参数传递).
从GPGME库中获取的示例:
typedef gpgme_error_t (*gpgme_passphrase_cb_t) (void *hook,
const char *uid_hint,
const char *passphrase_info,
int prev_was_bad,
int fd);
void gpgme_set_passphrase_cb (gpgme_ctx_t ctx,
gpgme_passphrase_cb_t cb,
void *hook_value);
Run Code Online (Sandbox Code Playgroud)
从概念上讲,函数指针加上void指针代表与C#(一个闭包)中的委托相同的东西.在进行这种P/Invoke调用时,是否有一种很好的,规范的方法来编组代理?
F#是否提供任何"标准"运算符集来处理Async计算表达式之外的monadic(特定)运算?我发现我的代码最终散落着许多本地运营商定义,如:
let (>>=) a b = async.Bind (a, b)
Run Code Online (Sandbox Code Playgroud)
如果给定了运营商的有多好是构成纯函数- <|,|>和>>等-我觉得我必须在这里失去了一些东西.
为了抢占可能的注释 - 计算表达式适用于某些事情,但是用于管道化一系列异步操作:
async {
let! a' = a
let! b' = b a'
return! c b'
}
Run Code Online (Sandbox Code Playgroud)
感觉不如:
a >>= b >>= c
Run Code Online (Sandbox Code Playgroud)