Back
fnil (clj)
(source)function
(fnil f x)
(fnil f x y)
(fnil f x y z)
Takes a function f, and returns a function that calls f, replacing
a nil first argument to f with the supplied value x. Higher arity
versions can replace arguments in the second and third
positions (y, z). Note that the function f can take any number of
arguments, not just the one(s) being nil-patched.
Examples
clojure/core.typed
(ns ^:skip-wiki clojure.core.typed.checker.nilsafe-utils
(:require [clojure.set :as set]
[clojure.core.typed :as t]))
(t/ann ^:no-check set-union
(t/All [x]
(t/IFn [-> (t/Set x)]
[(t/U nil (t/Set x)) -> (t/Set x)]
[(t/U nil (t/Set x)) (t/Set x) * -> (t/Set x)])))
(def set-union (fnil set/union #{}))
(t/ann ^:no-check set-difference
(t/All [x]
(t/IFn [(t/U nil (t/Set x)) -> (t/Set x)]
[(t/U nil (t/Set x)) (t/Set t/Any) * -> (t/Set x)])))
(def set-difference (fnil set/difference #{}))
clojure/core.typed
(ns clojure.core.typed.annotator.test.runtime-infer.gen-arglists
{:lang :core.typed
:core.typed {:features #{:runtime-infer}}
}
(:refer-clojure :exclude [*])
(:require [clojure.core.typed :as t]
[clojure.core :as core]
[clojure.spec.alpha :as s]
[clojure.pprint :refer [pprint]]))
(def *
(fn
([] 1)
([x] x)
([x & xs]
(reduce (fnil core/* 0M 0M) x xs))))
typedclojure/typedclojure
(ns ^:no-doc typed.ann.clojure
"Type annotations for the base Clojure distribution."
#?(:cljs (:require-macros [typed.ann-macros.clojure :as macros]))
(:require [clojure.core :as cc]
[typed.clojure :as t]
#?(:clj [typed.ann-macros.clojure :as macros])
#?(:clj typed.ann.clojure.jvm) ;; jvm annotations
#?(:clj clojure.core.typed))
#?(:clj
(:import (clojure.lang PersistentHashSet PersistentList
APersistentMap #_IPersistentCollection
#_ITransientSet
IRef)
(java.util Comparator Collection))))
cc/fnil (t/All [x y z a b :..] (t/IFn [[x b :.. b :-> a] x :-> [(t/Nilable x) b :.. b :-> a]]
[[x y b :.. b :-> a] x y :-> [(t/Nilable x) (t/Nilable y) b :.. b :-> a]]
[[x y z b :.. b :-> a] x y z :-> [(t/Nilable x) (t/Nilable y) (t/Nilable z) b :.. b :-> a]]))
typedclojure/typedclojure
(ns typed.clj.annotator.test.runtime-infer.gen-arglists
{:lang :core.typed
:core.typed {:features #{:runtime-infer}}
}
(:refer-clojure :exclude [*])
(:require [typed.clojure :as t]
[clojure.core :as core]
[clojure.spec.alpha :as s]
[clojure.pprint :refer [pprint]]))
(def *
(fn
([] 1)
([x] x)
([x & xs]
(reduce (fnil core/* 0M 0M) x xs))))
yetanalytics/dave
(ns com.yetanalytics.dave.ui.app.workbook.data
(:require [re-frame.core :as re-frame]
[com.yetanalytics.dave.workbook.data :as data]
[com.yetanalytics.dave.workbook.data.state :as state]
[com.yetanalytics.dave.workbook.data.lrs.client
:as lrs-client]
[clojure.core.async :as a :include-macros true]
[clojure.spec.alpha :as s]
[goog.string :refer [format]]
[goog.string.format]))
(re-frame/reg-event-fx
::set-state
;; called for a data source when loading is complete.
;; funcs check if their state is = to this before deriving results.
(fn [{:keys [db]}
[_
workbook-id
new-state
force?]]
(let [new-db (assoc-in
(if force?
(assoc-in db
[:workbooks
workbook-id
:data
:state]
new-state)
(update-in db
[:workbooks
workbook-id
:data
:state]
(fnil
(partial max-key :statement-idx)
state/init-state)
new-state))
[:workbooks
workbook-id
:data
:loading?]
false)]
{:db new-db}
;; here is where you would fire off reactive results, which we're currently not doing
#_(cond-> {:db new-db}
(not= db new-db)
(assoc :dispatch-n [[:workbook.question.function/result-all!
workbook-id]
[:db/save]])))))
(re-frame/reg-event-fx
::load
(fn [{:keys [db] :as ctx}
[_ workbook-id
idx-range
{:keys [status body] :as response}
then-dispatch]]
(let [
{data-type :type
data-state :state
:as data} (get-in db
[:workbooks
workbook-id
:data])
then-dispatch (case data-type
::data/file
[::set-state
workbook-id
(state/update-state
state/init-state
body)
true]
::data/lrs
then-dispatch)]
(if (= 200 status)
{:dispatch-n [;; TODO: fire off step functions if desired
#_[:workbook.question.function/step-all!
workbook-id
idx-range
body
;; pass continuation
then-dispatch]
then-dispatch
[::clear-errors workbook-id]]}
{:db (update-in db
[:workbooks
workbook-id
:data
:errors]
(fnil conj [])
{:type ::load-error
:message "Couldn't load data."
:workbook-id workbook-id
:response response})}))))
(re-frame/reg-event-fx
::change
(fn [{:keys [db] :as ctx}
[_
workbook-id
data-spec]]
(cond-> {:db (assoc-in db
[:workbooks
workbook-id
:data]
;; Force a fresh state
(merge data-spec
{:state state/init-state}))
;; this is where you would reset the state of queries
:dispatch [::ensure workbook-id]}
(= (:type data-spec) ::data/file)
(assoc :stop-timer
[::ensure workbook-id]))))