[Haskell-cafe] streaming with logs / metadata
Olaf Klinke
olf at aatal-apotheke.de
Tue Apr 9 19:53:27 UTC 2019
>> Anything beyond the Functor instance for (Either e), though, models exceptions that abort the computation as soon as the first Left arises. You seem to use the type in a different way which may be one reason why you do not find your functions implemented elsewhere. For logging or warnings, most Haskellers use something like a writer monad transformer. The underlying monad,
>>
>> Writer w a = (w,a)
>
> That's the thing I was saying destroys streaming. The problem is that
> it returns ([log], [a]), instead of [Either log a], so the
> interleaving has been lost.
>
Evan,
When you say interleaving, do you think of lists like the following?
[Left warning1,Right value 1,Left warning 2,Right value2,...]
The above is isomorphic to
[(warning1,value1),(warning2,value2),...]
I don't think that the writer monad destroys streaming. Below is a somewhat contrived, but ordinary use case.
{-- begin example --}
import Control.Monad.Writer -- from mtl
type Log = [String] -- some Monoid
half :: Int -> Writer Log Int
half x = case x `quotRem` 2 of
(y,0) -> return y
(y,1) -> writer (y,["Warning: "++(show x)++" was uneven."])
stream :: [Int]
stream = 4:8:5:3:7:2: error "broken stream"
(ys,warnings) = runWriter (mapM half stream)
{-- end example --}
ghci> -- load the example above
ghci> ys
[2,4,2,1,3,1*** Exception: broken stream
ghci> mapM_ putStrLn warnings
Warning: 5 was uneven.
Warning: 3 was uneven.
Warning: 7 was uneven.
*** Exception: broken stream
You see that there is some output before the error is reached, proving that both ys and warnings could be consumed in a streaming manner. Here it is important that the Log monoid's `mappend` function is not strict in the second argument. It would not, for example, work with
Log = Data.Sequence.Seq String
With mtl you could easily throw in a State monad component that keeps track of the position in the stream, so that warning messages can hint at the place where the warning originated.
Olaf
More information about the Haskell-Cafe
mailing list