From c80b8e4195e1c398026bc8ff6b3af7afafaa538a Mon Sep 17 00:00:00 2001 From: gusty <1261319+gusty@users.noreply.github.com> Date: Wed, 27 Aug 2025 15:14:30 +0200 Subject: [PATCH] Add overload to match on exception --- src/FSharpPlus/Control/Indexable.fs | 10 +++++++++- tests/FSharpPlus.Tests/Indexables.fs | 29 ++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/FSharpPlus/Control/Indexable.fs b/src/FSharpPlus/Control/Indexable.fs index bfe0f887a..d738a2d42 100644 --- a/src/FSharpPlus/Control/Indexable.fs +++ b/src/FSharpPlus/Control/Indexable.fs @@ -16,8 +16,10 @@ open FSharpPlus.Internals.MonadOps type Item = inherit Default1 + + static member inline InvokeOnInstance (k: 'K) (x: '``Indexable<'T>``) : 'T = (^``Indexable<'T>`` : (member get_Item : _ -> 'T) x, k) : 'T - static member inline Item (x: '``Indexable<'T>`` , k , []_impl: Default1) = (^``Indexable<'T>`` : (member get_Item : _ -> 'T) x, k) : 'T + static member inline Item (x: '``Indexable<'T>`` , k , []_impl: Default1) = Item.InvokeOnInstance k x : 'T static member inline Item (_: 'T when 'T: null and 'T: struct, _, _impl: Default1) = () static member Item (x: string , n , []_impl: Item ) = String.item n x @@ -37,6 +39,12 @@ type Item = type TryItem = inherit Default1 + + static member inline TryItem (x: '``Indexable<'T>``, k, []_impl: Default3) = + try Some (Item.InvokeOnInstance k x) with + | :? ArgumentException -> None + | _ -> reraise () + static member inline TryItem (x: '``Indexable<'T>``, k, []_impl: Default2) = let mutable r = Unchecked.defaultof< ^R> if (^``Indexable<'T>``: (member TryGetValue: _ * _ -> _) (x, k, &r)) then Some r else None diff --git a/tests/FSharpPlus.Tests/Indexables.fs b/tests/FSharpPlus.Tests/Indexables.fs index 1db1cfcd9..616239c8e 100644 --- a/tests/FSharpPlus.Tests/Indexables.fs +++ b/tests/FSharpPlus.Tests/Indexables.fs @@ -13,6 +13,34 @@ open Helpers module Indexables = + type NdXable1 = NdXable1 with static member TryItem (x, NdXable1) = if x = 1 then Some "Item retrieved" else None + type NdXable3 = NdXable3 with member _.get_Item x = if x = 1 then "Item retrieved" else invalidArg "item" (string x) + + [] + let testTryItem () = + let a1 = tryItem 0 NdXable1 + Assert.AreEqual (None, a1) + let b1 = tryItem 1 NdXable1 + Assert.AreEqual (Some "Item retrieved", b1) + + let dct = dict [1, "one"; 2, "two"] + let a2 = tryItem 0 dct + Assert.AreEqual (None, a2) + let b2 = tryItem 1 dct + Assert.AreEqual (Some "one", b2) + + let a3 = tryItem 0 NdXable3 + Assert.AreEqual (None, a3) + let b3 = tryItem 1 NdXable3 + Assert.AreEqual (Some "Item retrieved", b3) + + let lst = ["zero"; "one"; "two"] + let a4 = tryItem 10 lst + Assert.AreEqual (None, a4) + let b4 = tryItem 1 lst + Assert.AreEqual (Some "one", b4) + + [] let testCompileAndExecuteItem () = @@ -53,6 +81,7 @@ module Indexables = // let f = seq [1, "one"; 2, "two"] // let _ = item 1 f + () []