[Haskell-cafe] New version of itself

Carl Howells chowells79 at gmail.com
Sat Jun 4 17:10:11 UTC 2016


That's basically a Mealy machine.  See
https://hackage.haskell.org/package/machines-0.6/docs/Data-Machine-Mealy.html

newtype Logger a l = Logger (Mealy (a, Log l) (Log l))

Not quite an exact isomorphism since (,) is lifted, but it's close.

You're not actually doing anything weird there. That's a pretty
standard functional representation of a state machine.

On Sat, Jun 4, 2016 at 8:00 AM, Daniel Díaz <diaz.carrete at gmail.com> wrote:
> This is a bit of a tangent, but one can use the FoldM type from the foldl
> package to build composable logger-like things that perform effects.
>
> The semigroupoids package contains the Extend typeclass, which is basically
> "Comonad without extract". If we make FoldM an instance of Extend, we can
> "single-step" a FoldM with the function:
>
>      import Data.Functor.Extend (duplicated)
>      import qualified Control.Foldl as L
>
>      singleStep :: i -> L.FoldM IO i r -> IO (L.FoldM IO i r)
>      singleStep i :: flip L.foldM [i] . duplicated
>
> Which is basically a logging function.
>
> Also, since FoldM is an instance of Applicative, you can combine a list of
> loggers using sequenceA_.
>
> Another way to define a logger type would be with Cofree from the free
> package. Something like:
>
>      type Logger = Cofree ((->) String) (IO ())
>
> Which would also be an Applicative. One could then define stateful loggers
> using Cofree's unfold.
>
> I think the Cofree version has the advantage that you can be sure the
> logger's state only depends on the messages it receives (even as it emits IO
> actions on each step). The FoldM version, meanwhile, could perform some
> devious IO action to update its state.
>
> On Saturday, June 4, 2016 at 3:24:57 PM UTC+2, martin wrote:
>>
>> Hello all,
>>
>> I find myself frequentlly writing types like this
>>
>> data Logger a l = Lgr {
>>   runLogger :: a -> Log l -> (Log l, Logger a l)
>>   }
>>
>> The purpose is to give a logger a chance to carry an internal state. It
>> could e.g. choose to log only every n
>> invocations. To do this it must keep track of how many times it has been
>> called. I want to leave such things private to
>> the Logger.
>>
>>
>> (1) I know that this is not an unusal thing to do, but it has an OO feel
>> to it. Is there a more functional alternative
>> to it. Should I just not worry?
>>
>> (2) I can write a combinator which creates a Logger from a list of
>> Loggers. Since each Logger potentially returns a new
>> version of itself, I must always re-assemble the combined logger from all
>> the returned new versions. I am worried that
>> this is a costly operation, particularly when most Loggers just return
>> themselves unaltered. I don't have any hard
>> numbers about the performance penalty though.
>>
>> These Loggers are used in a discrete-event-simulation and they will get
>> called many times (once for each event), but
>> only occastionally actually write to the Log.
>> _______________________________________________
>> Haskell-Cafe mailing list
>> Haskel... at haskell.org
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>


More information about the Haskell-Cafe mailing list