我对设计和使用结果有一个快速的问题。 我已经阅读了FSharpForFunAndProfit上有关Railway Oriented Programming的出色文章,它确实符合我的需要,因为我需要访问数据库中的数据,并且某些数据可能不可用(因此会产生错误)。 / p>
假设我拥有以下域
type Main = A * B
type B =
{ B1 of float
B2 of string } // or any type, just took 2 simple ones)
如果我不使用Result,则可以轻松访问main:Main的所有内容
let a = main |> fst
let b1 = (snd B).B1
但是,假设我要使用类似这样的函数来创建Main
val createMain : x:sometihng -> Result<Main, 'T>
然后我知道要访问该主对象中的A(在Result.Ok情况下),我可以使用以下代码:
let fail x =
Result.Error x
let succeed x =
Result.Ok x
let either successFunc failureFunc twoTrackInput =
match twoTrackInput with
| Result.Ok s -> successFunc s
| Result.Error f -> failureFunc f
let map f =
either (f >> succeed) fail
在这种情况下,我可以编写以下内容:
let a = main |> map fst
我会得到一个
Result<A, 'T>
但是我如何轻松访问b1? 我知道我可以编写类似
的函数let getB1 main =
match main with
| Result.Ok -> (snd main).B1
| Result.Error t -> Result.Error t
但是,我将需要为每个参数编写一个函数,这非常不方便。
答案 0 :(得分:3)
您需要编写一些函数,类型为Main,并将其映射为Result。
换句话说,只需编写一堆对您的基本类型进行操作的函数,然后将它们适当地映射/绑定到您的Result类型。
因此,无论您想做什么,都编写一个将其执行为基本类型的函数。然后,在您具有“结果”类型的级别,将功能映射到它。
因此,在较高级别上,您输入结果并输出不同的结果。在较低级别,您可以使用基本类型。