Zin*_*ust 5 f# functional-programming pattern-matching
我对F#世界很陌生,目前正试图尝试功能.试图找到新的技术,使它们更紧凑和灵活,并从C#类似的编码风格.所以我有一个非常难看的代码,我不断检查和模式匹配:
type StringChecking =
| Success of string
| Fail
let StringProcessor(str : string) =
let newstr = modifyFn str
let result = checkFn newstr
match result with
| true -> Success result
| false ->
let newstr' = modifyFn' str
let result' = checkFn newstr'
match result' with
| true -> Success newstr'
| false ->
let newstr'' = modifyFn'' str
let result'' = checkFn newstr''
match result'' with
| true -> Success newstr''
| false ->
Fail
Run Code Online (Sandbox Code Playgroud)
是否有一些有用的技术可以帮助我消除所有这些阶段,使我的代码更优雅.对不起,如果问题看起来很尴尬或愚蠢,但我真的想对这个问题做些什么,因为我想在我的某个项目中使用它.我已经厌倦了在C#中不断检查.感谢您的时间和建议.
这假设目标是在一系列步骤中重复转换对象,此时仅在成功完成前一步骤时才执行下一步骤.这将由F#的Option类型封装在这里.
如果你在简洁之后,你可能会比某种一元的束缚更糟糕.
let (>>=) arg f = // bind operator
match arg with
| Some x -> f x
| None -> None
let checkWith checker x =
if checker x then Some x else None
"sample String"
|> (modifyFn >> checkWith checkFn)
>>= (modifyFn' >> checkWith checkFn')
>>= (modifyFn'' >> checkWith checkFn'')
Run Code Online (Sandbox Code Playgroud)
但你确实注意到流水线操作的第一步.这是由计算开始时的展开值产生的.从而:
Success "sample String"
>>= (modifyFn >> checkWith checkFn)
>>= (modifyFn' >> checkWith checkFn')
>>= (modifyFn'' >> checkWith checkFn'')
Run Code Online (Sandbox Code Playgroud)
如果您想要修改和验证相同的原始值而不是上一步的结果,那么我们只需忽略它.
let str ="sample String"
modifyFn str |> checkWith checkFn
>>= (fun _ -> modifyFn' str |> checkWith checkFn')
>>= (fun _ -> modifyFn'' str |> checkWith checkFn'')
Run Code Online (Sandbox Code Playgroud)
如果计算在步骤成功完成时终止,否则继续执行替代步骤,我们将具有不同的签名.类似于F#的defaultArg函数(arg:'T option -> defaultvalue:'T > 'T),我将提出类似绑定defaultBy:
let defaultBy c a f =
match a with
| None -> f c
| x -> x
let (>?=) f = defaultBy "sample string" f
"sample string"
|> (modifyFn >> checkWith checkFn)
>?= (modifyFn' >> checkWith checkFn')
>?= (modifyFn'' >> checkWith checkFn'')
Run Code Online (Sandbox Code Playgroud)