[英]Constructing a record with a power of Applicative in F#
Suppose there is a type r = {A : int; B : string; C : int; D : string}
假设有一个
type r = {A : int; B : string; C : int; D : string}
type r = {A : int; B : string; C : int; D : string}
type r = {A : int; B : string; C : int; D : string}
and a some values: type r = {A : int; B : string; C : int; D : string}
和一些值:
let aOptional : int option = ...
let bOptional : string option = ...
let cOptional : int option = ...
let dOptional : string option = ...
How can r optional
could be constructed from them eleganlty (without nested case-stuff, etc.)? 如何从他们的eleganlty构建
r optional
(没有嵌套的case-stuff等)?
Btw, here is how it could be done in haskell with Control.Applicative
: 顺便说一句,这是如何在haskell中使用
Control.Applicative
:
data R = R { a :: Integer, b :: String, c :: Integer, d :: String}
R <$> aOptional <*> bOptional <*> cOptional <*> dOptional :: Maybe R
Looking for something equivalent in fsharp. 寻找fsharp中的等价物。
The only way I know (using applicatives) is by creating a function to construct the record: 我知道的唯一方法(使用applicatives)是通过创建一个函数来构造记录:
let r a b c d = {A = a; B = b; C = c; D = d}
Then you can do: 然后你可以这样做:
> r </map/> aOptional <*> bOptional <*> cOptional <*> dOptional ;;
val it : R option
You can define map
and <*>
yourself, but if you want a generic implementation try that code with F#+ or if you want to use FsControl directly you can write the code this way: 您可以自己定义
map
和<*>
,但是如果您想要通用实现,请尝试使用F#+代码,或者如果您想直接使用FsControl ,您可以这样编写代码:
#r "FsControl.Core.dll"
open FsControl.Operators
let (</) = (|>)
let (/>) f x y = f y x
// Sample code
type R = {A : int; B : string; C : int; D : string}
let r a b c d = {A = a; B = b; C = c; D = d}
let aOptional = Some 0
let bOptional = Some ""
let cOptional = Some 1
let dOptional = Some "some string"
r </map/> aOptional <*> bOptional <*> cOptional <*> dOptional
// val it : R option = Some {A = 0; B = ""; C = 1; D = "some string";}
UPDATE : Nuget packages are available now. 更新 : Nuget包现已上市。
The straightforward way is: 直截了当的方式是:
match aOptional, bOptional, cOptional, dOptional with
| Some a, Some b, Some c, Some d -> Some {A=a; B=b; C=c; D=d}
| _ -> None
or, with a maybe monad : 或者,有一个monad :
let rOptional =
maybe {
let! a = aOptional
let! b = bOptional
let! c = cOptional
let! d = dOptional
return {A=a; B=b; C=c; D=d}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.