1

I have a basic append function

let append item list = item  :: list

And i have a' list option and option Some("something")

let listOption = Some []

I want to add the value "something" to listOption. How can I do it without using pattern matching and Option.get but by lifting append function?

Any help would be appreciated

Tartar
  • 5,149
  • 16
  • 63
  • 104

3 Answers3

0

You can use maybe computation expression

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
Lanayx
  • 2,731
  • 1
  • 23
  • 35
0

It looks like a home work...

If you want to add a value (not an option) at the head of a list option, you can simply do this which will return None if the list option is None:

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

liftedAppend signature is:

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

But talking about lifting stricto sensu, as the signature of your append function is:

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

the signature of the lifted function should be:

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

That means the first argument have to be an option and I guess you want to check if it's Some or None. If so attentively read other's replies.

You can use something like this, which the de-sugared Lanayx's computation expression.

let liftedAppend optItem optList =
    optList |> Option.bind (fun list -> 
        optItem |> Option.bind (fun item -> Some (item :: list)))
gileCAD
  • 2,295
  • 1
  • 10
  • 10
-1

This works:

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

but to create a lifted append:

let liftedAppend v = Option.map (append v)

listOption 
|> liftedAppend 11
|> printfn "%A" // Some [11]

The signature of the functions are:

  • val append : 'a -> 'a list > 'a list
  • val liftedAppend: 'a -> 'a list option -> 'a list option

To pass both parameters as options you can use Option.map2:

let liftedAppend2 vO = vO |> Option.map2 append

listOption 
|> liftedAppend2 (Some 11)
|> printfn "%A"  // Some [11]

Which has signature:

  • val liftedAppend2: a option -> 'a list option -> 'a list option
AMieres
  • 4,944
  • 1
  • 14
  • 19