aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/abstract/apply.lux
blob: da787a54aab64543bf7832e755ef28766ba056e4 (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
(.module:
  [library
   [lux #*]]
  [//
   [monad (#+ Monad)]
   ["." functor (#+ Functor)]])

(interface: #export (Apply f)
  {#.doc "Applicative functors."}
  (: (Functor f)
     &functor)
  (: (All [a b]
       (-> (f (-> a b)) (f a) (f b)))
     apply))

(implementation: #export (compose f_monad f_apply g_apply)
  {#.doc "Applicative functor composition."}
  (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.compose (get@ #&functor f_apply) (get@ #&functor g_apply)))
  
  (def: (apply fgf fgx)
    ## TODO: Switch from this version to the one below (in comments) ASAP.
    (let [fgf' (\ f_apply apply
                  (\ f_monad wrap (\ g_apply apply))
                  fgf)]
      (\ f_apply apply fgf' fgx))
    ## (let [applyF (\ f_apply apply)
    ##       applyG (\ g_apply apply)]
    ##   ($_ applyF
    ##       (\ f_monad wrap applyG)
    ##       fgf
    ##       fgx))
    ))