【问题标题】:F#: appending the value of an option to list optionF#:将选项的值附加到列表选项
【发布时间】:2019-04-01 13:26:46
【问题描述】:

我有一个基本的append 函数

let append item list = item  :: list

我有一个'列表选项和选项Some("something")

let listOption = Some []

我想将值"something" 添加到listOption。如何在不使用模式匹配和Option.get 而是通过提升append 功能的情况下做到这一点?

任何帮助将不胜感激

【问题讨论】:

    标签: function functional-programming f# lifting


    【解决方案1】:

    你可以使用也许计算表达式

    type MaybeBuilder() =
        member this.Bind(m, f) = Option.bind f m
        member this.Return(x) = Some x
    
    let maybe = new MaybeBuilder()
    let append item list = item  :: list
    let appendLifted item list =
        maybe {
            let! l = list
            let! i = item
            return append i l
        }
    
    [<EntryPoint>]
    let main argv =
        appendLifted (Some "abc") (Some [])
        0
    

    【讨论】:

      【解决方案2】:

      它看起来像一个家庭作业......

      如果您想在列表选项的开头添加一个值(不是选项),您可以简单地执行此操作,如果列表选项为 None,则返回 None:

      let liftedAppend item optList =
          optList |> Option.bind (fun list -> Some (item :: list))
      

      liftedAppend 签名为:

      'a -> 'a list option -> 'a list option
      

      但是谈论提升严格意义上的,因为您的附加功能的签名是:

      'a -> 'a list -> 'a list
      

      提升函数的签名应该是:

      'a option -> 'a list option -> 'a list option
      

      这意味着第一个参数必须是一个选项,我猜你想检查它是 Some 还是 None。如果是这样,请仔细阅读其他人的回复。

      你可以使用这样的东西,去糖化 Lanayx 的计算表达式。

      let liftedAppend optItem optList =
          optList |> Option.bind (fun list -> 
              optItem |> Option.bind (fun item -> Some (item :: list)))
      

      【讨论】:

        【解决方案3】:

        这行得通:

        listOption 
        |> Option.map (append 11)
        |> printfn "%A"  // Some [11]
        

        但要创建一个提升的append

        let liftedAppend v = Option.map (append v)
        
        listOption 
        |> liftedAppend 11
        |> printfn "%A" // Some [11]
        

        函数的签名是:

        • val append : 'a -&gt; 'a list &gt; 'a list
        • val liftedAppend: 'a -&gt; 'a list option -&gt; 'a list option

        要将两个参数作为选项传递,您可以使用Option.map2

        let liftedAppend2 vO = vO |> Option.map2 append
        
        listOption 
        |> liftedAppend2 (Some 11)
        |> printfn "%A"  // Some [11]
        

        有签名的:

        • val liftedAppend2: a option -&gt; 'a list option -&gt; 'a list option

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-09-05
          • 1970-01-01
          • 2011-07-07
          • 1970-01-01
          • 2013-11-08
          • 1970-01-01
          相关资源
          最近更新 更多