Skip to content

Commit b6ea9bb

Browse files
authored
Merge pull request #463 from Choc13/free-lift3-test
Fix Free.map3
2 parents 350f5cb + 8d3003d commit b6ea9bb

File tree

2 files changed

+41
-5
lines changed

2 files changed

+41
-5
lines changed

src/FSharpPlus/Data/Free.fs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,11 @@ module Free =
6262
loop y x
6363

6464
let inline map3 (f: 'T->'U->'V->'W) (x: Free<'``Functor<'T>``,'T>) (y: Free<'``Functor<'U>``,'U>) (z: Free<'``Functor<'V>``,'V>) : Free<'``Functor<'W>``,'W> =
65-
let rec loop (y: Free<_,_>) (x: Free<_,_>) (z: Free<_,_>) =
65+
let rec loop (y: Free<_,_>) (z: Free<_,_>) (x: Free<_,_>) =
6666
match run x with
67-
| Pure x -> map2<'U,'V,'W,'``Functor<'U>``,'``Functor<Free<'Functor<'U>,'U>>``,'``Functor<Free<'Functor<'V>,'V>>``,'``Functor<Free<'Functor<'W>,'W>>``,'``Functor<'V>``,'``Functor<'W>``> (f x) y z : Free<'``Functor<'W>``,'W>
68-
| Roll (x: ^``Functor<Free<'Functor<'T>,'T>>``) -> Roll (Map.Invoke (loop y: Free<'``Functor<'T>``,'T> -> _) x: '``Functor<Free<'Functor<'W>,'W>>``)
69-
loop y x z
67+
| Pure x -> map2<'U,'V,'W,'``Functor<'U>``,'``Functor<Free<'Functor<'U>,'U>>``,'``Functor<Free<'Functor<'W>,'W>>``,'``Functor<Free<'Functor<'V>,'V>>``,'``Functor<'V>``,'``Functor<'W>``> (f x) y z : Free<'``Functor<'W>``,'W>
68+
| Roll (x: ^``Functor<Free<'Functor<'T>,'T>>``) -> Roll (Map.Invoke (loop y z: Free<'``Functor<'T>``,'T> -> _) x: '``Functor<Free<'Functor<'W>,'W>>``)
69+
loop y z x
7070

7171
/// Folds the Free structure into a Monad
7272
let inline fold (f: '``Functor<'T>`` -> '``Monad<'T>``) (x: Free<'``Functor<'U>``,'U>) : '``Monad<'U>`` =
@@ -105,4 +105,4 @@ type Free<'``functor<'t>``,'t> with
105105

106106
static member Delay (x: unit -> Free<'``Functor<'T>``,'T>) = x ()
107107

108-
#endif
108+
#endif

tests/FSharpPlus.Tests/Free.fs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,3 +316,39 @@ module Fold =
316316
|> Identity.run
317317

318318
areStEqual (Ok { Id = FooId "1"; Name = "test" }) response
319+
320+
module Lift3 =
321+
322+
type Instruction<'next> =
323+
| Read of int * (string -> 'next)
324+
static member Map(i, f) =
325+
match i with
326+
| Read (x, next) -> Read(x, next >> f)
327+
328+
let read x = Read(x, id) |> Free.liftF
329+
330+
type ApplicativeBuilder<'a>() =
331+
inherit MonadFxStrictBuilder<'a>()
332+
333+
member inline _.BindReturn(x, f) = map f x
334+
335+
let applicative<'a> = ApplicativeBuilder<'a>()
336+
337+
[<Test>]
338+
let ``should be able to use applicative CE which requires Lift3`` () =
339+
let program =
340+
applicative {
341+
let! a = read 1
342+
and! b = read 2
343+
and! c = read 3
344+
return a, b, c
345+
}
346+
347+
let result =
348+
program
349+
|> Free.fold
350+
(function
351+
| Read (i, next) -> i |> string |> next |> result)
352+
|> Identity.run
353+
354+
areStEqual result ("1", "2", "3")

0 commit comments

Comments
 (0)