## Copyright (c) Eduardo Julian. All rights reserved. ## This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. ## If a copy of the MPL was not distributed with this file, ## You can obtain one at http://mozilla.org/MPL/2.0/. (;module: lux (lux/control monoid ["A" applicative #*] functor ["M" monad #*])) (type: #export (Log l a) [l a]) (struct: #export Functor (All [l] (Functor (Log l))) (def: (map f fa) (let [[log datum] fa] [log (f datum)]))) (struct: #export (Applicative mon) (All [l] (-> (Monoid l) (Applicative (Log l)))) (def: functor Functor) (def: (wrap x) [(:: mon unit) x]) (def: (apply ff fa) (let [[log1 f] ff [log2 a] fa] [(:: mon append log1 log2) (f a)]))) (struct: #export (Monad mon) (All [l] (-> (Monoid l) (Monad (Log l)))) (def: applicative (Applicative mon)) (def: (join mma) (let [[log1 [log2 a]] mma] [(:: mon append log1 log2) a]))) (def: #export (log l) (All [l] (-> l (Log l Unit))) [l []]) (struct: #export (LogT Monoid Monad) (All [l M] (-> (Monoid l) (Monad M) (Monad (All [a] (M (Log l a)))))) (def: applicative (A;compA (get@ #M;applicative Monad) (Applicative Monoid))) (def: (join MlMla) (do Monad [[l1 Mla] (: (($ +1) (Log ($ +0) (($ +1) (Log ($ +0) ($ +2))))) MlMla) [l2 a] Mla] (wrap [(:: Monoid append l1 l2) a])))) (def: #export (lift-log Monoid Monad) (All [l M a] (-> (Monoid l) (Monad M) (-> (M a) (M (Log l a))))) (lambda [ma] (do Monad [a ma] (wrap [(:: Monoid unit) a]))))