         [_ (connect-to-db-m)
          _ (connect-to-api-m)]
         (prn "Done.")))
+
+(defn connect-to-db-m-2 []
+  (do-m reader-m
+        [db-uri (asks :db-uri)]
+        (str "Connected to db at %s" db-uri)))
+
+(defn connect-to-api-m-2 []
+  (do-m reader-m
+        [api-key (asks :api-key)]
+        (str "Connected to api with key %s" api-key)))
+
+(defn run-app-m-2 []
+  (do-m reader-m
+        [dbinfo (connect-to-db-m-2)
+         apiinfo (connect-to-api-m-2)]
+        (str "dbinfo -> " dbinfo "apiinfo -> " apiinfo)))
 
 (macroexpand '(do-m reader-m
                     [_ (connect-to-db-m)

;;但是貌似defprotocol和reify的组合本身就可以这样弄 就是repo那里使用let绑定为mk-user-repo的位置 用reader monad会让代码描述性更强 repo就是单独传入的一个module一样的意思
;;如果不用reader monad那么用mk-user-repo函数生成的repo值还需要显示的被传入clone!函数 现在只要在最外层显式地写一次就好了
;;其实这样看来 上面传递env的那个例子也算是一种依赖注入 依赖就是env这个上下文中保存的信息

((run-app-m) {:db-uri  "user:passwd@host/dbname"
              :api-key "AF167"})

;;从上面donotation这个宏的展开结果就可以看到 可以利用闭包性将参数传入最终的处理函数中 之前每一层的闭包参数都是_ 都忽略了 但是是可以放入参数的
((run-app-m-2) {:db-uri  "user:passwd@host/dbname"
                :api-key "AF167"})

;;感觉屌飞了 黑魔法啊 reader monad扔出来的就是一个单参函数接受传入的配置 并且可以用ask获取到传入的配置值
;;有了reader monad 就不需要把配置手动显式的传给每一个依赖配置的函数 可以让内部的业务代码更加整洁 当然团队内部平均水平肯定要都在一条线上

