Skip to content

Instantly share code, notes, and snippets.

@sritchie
Created April 9, 2015 15:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sritchie/e2fd24b18ea5cdac6ed7 to your computer and use it in GitHub Desktop.
Save sritchie/e2fd24b18ea5cdac6ed7 to your computer and use it in GitHub Desktop.
State Transformer over Optional Transformer over Logger...
-- | Remove all duplicate integers from a list. Produce a log as you go.
-- If there is an element above 100, then abort the entire computation and produce no result.
-- However, always keep a log. If you abort the computation, produce a log with the value,
-- "aborting > 100: " followed by the value that caused it.
-- If you see an even number, produce a log message, "even number: " followed by the even number.
-- Other numbers produce no log message.
--
-- /Tip:/ Use `filtering` and `StateT over (`OptionalT` over `Logger` with a @Data.Set#Set@).
--
-- >>> distinctG $ listh [1,2,3,2,6]
-- Logger ["even number: 2","even number: 2","even number: 6"] (Full [1,2,3,6])
--
-- >>> distinctG $ listh [1,2,3,2,6,106]
-- Logger ["even number: 2","even number: 2","even number: 6","aborting > 100: 106"] Empty
distinctG :: (Integral a, Show a) => List a -> Logger Chars (Optional (List a))
distinctG xs =
let stringcat x y = fromString (x P.++ show y)
efn a = StateT
(OptionalT .
(\ret ->
if a > 100
then log1 (stringcat "aborting > 100: " a) Empty
else (if even a
then log1 (stringcat "even: " a)
else pure) (Full ret)) .
(S.notMember a &&& S.insert a))
in runOptionalT (evalT (filtering efn xs) S.empty)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment