aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/abstract/apply.lux
blob: 90fedf8d342766bcd2608e357e5d4edc998e320d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
(.using
 [library
  [lux "*"
   ["@" target]]]
 [//
  [monad {"+" Monad do}]
  ["[0]" functor {"+" Functor}]])

(type: .public (Apply f)
  (Interface
   (is (Functor f)
       functor)
   (is (All (_ a b)
         (-> (f a) (f (-> a b)) (f b)))
       on)))

(implementation: .public (composite f_monad f_apply g_apply)
  (All (_ F G)
    (-> (Monad F) (Apply F) (Apply G)
        ... TODO: Replace (All (_ a) (F (G a))) with (functor.Then F G)
        (Apply (All (_ a) (F (G a))))))
  
  (def: functor
    (functor.composite (the functor f_apply)
                       (the functor g_apply)))
  
  (def: (on fgx fgf)
    ... TODO: Switch from this version to the one below (in comments) ASAP.
    (for @.old (let [fgf' (# f_apply on
                             fgf
                             (# f_monad in (function (_ gf gx) (# g_apply on gx gf))))]
                 (as_expected (# f_apply on (as_expected fgx) (as_expected fgf'))))
         (let [fgf' (# f_apply on
                       fgf
                       (# f_monad in (function (_ gf gx) (# g_apply on gx gf))))]
           (# f_apply on fgx fgf')))
    ... (let [applyF (# f_apply on)
    ...       applyG (# g_apply on)]
    ...   (all applyF
    ...       fgf
    ...       (# f_monad in applyG)
    ...       fgx))
    ))