Chaining method calls and "bubbling" the results
How about making inMem &amp; co "bracket" functions? Like follows:

import Control.Monad.Writer

type M a = Writer String a
type LoadFunc a b = (a -&gt; M b) -&gt; a -&gt; M b

type Query = String
type Result = ()

inMem :: LoadFunc Query Result
inMem _ "hi" = tell "Found in mem. "
inMem f q    = f q &gt;&gt; tell "Added to mem. "

renDisk :: LoadFunc Query Result
renDisk _ "foo" = tell "Found rendered. "
renDisk f q     = f q &gt;&gt; tell "Added rendered. "

onDisk :: LoadFunc Query Result
onDisk _ "bar" = tell "Found on disk. "
onDisk f q     = f q &gt;&gt; tell "Now on disk. "

tester :: [LoadFunc Query Result] -&gt; Query -&gt; M Result
tester = foldr ($) notFound
  where notFound q = tell "Not found!"


Run using runWriter $ tester [inMem,renDisk,onDisk] "bar"

This should give you the control flow you seek - as well as enough room for extension by replacing the monad as required. You could for example have notFound throw an exception using an Error monad instead (which would probably make sense).