How to implement Prisms to use with FSharpPlus?

I sort of know that how Prisms work (basically a partial Lens), but I am not extremely sure about how to implement proper Prisms to be used with FSharpPlus, since their documentation only mentions Lens rather than Prisms.

Suppose I have a DU like this:

type Ex =
| A with string
| B with int

Is this the right way to implement prisms?
(Deduced from the signature of FSharpPlus.Lens.preview)

module Ex =
  let inline A_ f p =
    f p
    <&> fun x ->
      match p with
      | A _ -> First(Some(A x))
      | _ -> First None

  let inline B_ f p =
    f p
    <&> fun x ->
      match p with
      | B _ -> First(Some(B x))
      | _ -> First None

You can use the prism' helper function for cases like this one:

#r "nuget: FSharpPlus"

open FSharpPlus
open FSharpPlus.Lens

type Ex =
| A of string
| B of int

module Ex =
  let inline A_ f p = prism' A (function A x -> Some x | _ -> None) f p
  let inline B_ f p = prism' B (function B x -> Some x | _ -> None) f p

let a0 = A "hello"
let b0 = B 42

let x1 = preview Ex.A_ a0
// val x1: Ex option = Some "hello"

let x2 = preview Ex.B_ a0
// val x2: int option = None

let x3 = preview Ex.A_ b0
// val x3: string option = None

let x4 = preview Ex.B_ b0
// val x4: int option = Some 42

Thanks! I have browsed the document again and did find it. But I also find a prism helper with slightly different signature, what is the purpose of that function?

It’s basically the same function but using Result instead of Option to permit the types of 's and 't to differ.

And under what cases might it differ? I can’t really think of one if it’s only for reading DUs.

What if the value inside the DU is generic and you want to “set” it to a different value of a different type?