Skip to content

Commit ad89c2a

Browse files
committed
Adapt bind for non-sealed types
1 parent 231da23 commit ad89c2a

File tree

2 files changed

+13
-7
lines changed

2 files changed

+13
-7
lines changed

src/FSharpPlus/List.fs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,14 @@ module ListT =
5858
loop l1 l2 : ListT<'mt>
5959

6060
let inline bind f (source: ListT<'mt>) : ListT<'mu> =
61-
let rec loop f input =
62-
wrap (
63-
(unwrap input : 'mit) >>= function
61+
let _mnil _ = (result Unchecked.defaultof<'t> : 'mt) >>= fun (_: 't) -> (result Unchecked.defaultof<'u>) : 'mu
62+
let rec loop f (ListT input) =
63+
ListT (
64+
(unbox input : 'mit) >>= function
6465
| Nil -> result <| (Nil : ListTNode<'mu,'u>) : 'miu
6566
| Cons (h:'t, t: ListT<'mt>) ->
66-
let ( res) = concat (f h: ListT<'mu>) (loop f t )
67-
unwrap res : 'miu)
67+
let res = concat (f h: ListT<'mu>) (loop f t)
68+
unwrap res : 'miu)
6869
loop f source : ListT<'mu>
6970

7071
let inline unfold (f:'State -> '``M<('T * 'State) option>``) (s:'State) : ListT<'MT> =

tests/FSharpPlus.Tests/ListT.fs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ open NUnit.Framework
77
open FsCheck
88
open Helpers
99
open System.Collections.Generic
10+
open System.Threading.Tasks
1011

1112
module BasicTests =
1213
[<Test>]
@@ -25,8 +26,12 @@ module BasicTests =
2526

2627
// Compile tests
2728
let binds () =
28-
let res = listT ( [| [1..4] |]) >>= fun x -> listT ( [| [x * 2] |])
29-
() // but for some reason it doesn't work for Task, ResizeArray, Lazy and seq
29+
let res1 = listT [| [1..4] |] >>= fun x -> listT [| [x * 2] |]
30+
let res2 = listT (Task.FromResult [1..4]) |> ListT.bind (fun x -> listT (Task.FromResult [x * 2]))
31+
let res3 = listT (ResizeArray [ [1..4] ]) |> ListT.bind (fun x -> listT (ResizeArray [ [x * 2] ]))
32+
let res4 = listT (lazy [1..4]) |> ListT.bind (fun x -> listT (lazy ( [x * 2])))
33+
let (res5: ListT<_ seq>) = listT (seq [ [1..4] ]) |> ListT.bind (fun x -> listT (seq [ [x * 2] ]))
34+
() // Note: seq needs type annotation, the non-sealead types don't work with generic >>= (internal error, unsolved type var)
3035

3136
let bind_for_ideantity () =
3237
let res = listT (Identity [1..4]) >>= fun x -> listT (Identity [x * 2])

0 commit comments

Comments
 (0)