(未能“理解”FParsec,我按照我在某处读到的建议开始尝试自己编写一个小解析器。不知何故,我发现了一个尝试单子化它的机会,现在我有 N 个问题......)
这是我的“结果”类型(简化)
type Result<'a> =
| Success of 'a
| Failure of string
这是计算表达式构建器
type ResultBuilder() =
member m.Return a = Success(a)
member m.Bind(r,fn) =
match r with
| Success(a) -> fn a
| Failure(m) -> Failure(m)
在第一个示例中,一切都按预期工作(编译):
module Parser =
let res = ResultBuilder()
let Combine p1 p2 fn =
fun a -> res { let! x = p1 a
let! y = p2 a
return fn(x,y) }
我的问题在这里:我希望能够在“组合”函数中捕获任何失败并返回失败,但它说我应该定义一个“零”。
let Combine2 p1 p2 fn =
fun a -> res { let! x = p1 a
let! y = p2 a
try
return fn(x,y)
with
| ex -> Failure(ex.Message) }
不知道我应该在零中返回什么,我只是扔了member m.Zero() = Failure("hello world")
,现在它说我需要TryWith
。
所以:
member m.TryWith(r,fn) =
try
r()
with
| ex -> fn ex
现在它想要延迟,所以member m.Delay f = (fun () -> f())
.
此时它显示(在ex -> Failure
),,This expression should have type 'unit', but has type 'Result<'a>'
我举起双臂转向你们......
播放链接: http: //dotnetfiddle.net/Ho1sGS