Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
Andi Miller
@andimiller
the StateT approach only gives you Sync
but it means you have your state when you're in raiseError
matfournier
@matfournier
That might be enough.
I did it like that, warning, probably a terrible idea
matfournier
@matfournier
Hah
I mean, the code I've inherited does this with a mutable global that is cleared on every request, so anything is an improvement.
Gavin Bisesi
@Daenyth
I think the Context approach is nice because it's quite explicit and obvious
you could also put it in, wrapping the global you currently have, and then change the behavior just by passing in one that isn't wrapping the global any more
matfournier
@matfournier
I mean yes I can make something new at the top level and manually bump it down to all my calls. It would be nicer if something was inside something like Writer but also MonadError for being able to deal with random jvm exceptions. I am inside an F[Either[Error,A]] and both the error and a failed F get turned into logging messages at the edge of the program right now/.
Gavin Bisesi
@Daenyth
it's hard because you have two failure channels
WriterT[F, Log, ?] as your F would be fine except then F failures don't get logged
You almost need an outer Either[Throwable to catch the F errors
matfournier
@matfournier
I know. The two failure channels is annoying.
Gavin Bisesi
@Daenyth
this is a case where BIO/UIO would be really helpful
but there's not a good cats-generic way for that right now
matfournier
@matfournier
Unfortunately due to the way this is setup + the team, don't think I can use BIO yet
Gavin Bisesi
@Daenyth
You could change Either[Error to Throwable :+: Error :+: A maybe
matfournier
@matfournier
F[Either[Error,A]] atleast roughly breaks down to expected errors in the either, and super-unexpected errors in the F.
Gavin Bisesi
@Daenyth
yeah those "super unexpected" ones have a way of being really common IME
and exceptionally worth logging
matfournier
@matfournier
Yep. Which I am. I just want better logging with a little bit more tracing. Sigh. Thanks for the help!
Rob Norris
@tpolecat
If you have state you need to preserve in case of failure you can stuff it in a Ref.
Arnau Abella
@monadplus
modo compiles, modo2 doesn't. What am I missing ? Maybe it's just type inference
def st: State[S, List[A]]

def modo(f: A => B): IndexedState[S, T, List[A]] =
    Bifunctor[IndexedStateT[Eval, S, ?, ?]].leftMap(st)(traversal.modify(f))

  def modo2(f: A => B): IndexedState[S, T, List[A]] =
    (st: IndexedStateT[Eval, S, S, List[A]]).leftMap(traversal.modify(f))
Arnau Abella
@monadplus
@tpolecat I totally forgot about asking you about Yoneda and Coyoneda. Are you still willing to explain it ?
Arnau Abella
@monadplus
Isn't yoneda similar to a functor ? (forall b. (a -> b) -> f b) ~ f a
Fabio Labella
@SystemFw
Coyoneda is the free functor
and I'd recommend starting from there
Arnau Abella
@monadplus
Is there any resource you would recommend reading ?
Fabio Labella
@SystemFw
tbh most of them are focused on the category theory implications, which I consider (in general) as a separate thing from programming. What does your interest in learning about Yoneda and Coyoneda lie?
Arnau Abella
@monadplus
I just wanted to learn the concept (not in depth) for general knowledge. I am not going to work with free monads in the near future.
By concept, I mean the implications in programming, not in category theory.
Fabio Labella
@SystemFw
then I'd only focus on Coyoneda, and in particular around foldMap
by favourite explanation of free structure is in terms of abstract algebra, not category theory, in particular about the universal property, which is exactly what foldMap is
e.g. look at foldMap on List, Coyoneda, Free and FreeApplicative
if you look at List/Coyoneda/Free/FreeApplicative as programs of a specific shape, which are parameterised by their instructions, then foldMap says: "give me a translation between instructions, and I'll give you a translation between programs "
Fabio Labella
@SystemFw
(free in this context means that the property above holds for all target programs, e.g. you can always recover any other monoid from List, if you can translate individual elements of that List to the target monoid)
I'm probably being overly cryptic, ask further questions either here or in PM :)
but basically my pov (unless you're interested in CT) is that the free property is worth knowing, at which point "Coyoneda is the free functor" is an adequate explanation for programming
Arnau Abella
@monadplus
foldMap for list folds a list of monoids but for free, it folds a list of monads, right ?
Fabio Labella
@SystemFw
no, it folds a Free monad
I'd recommend writing the type down for foldMap on List, Free, FreeApplicative and Coyoneda
I'll write them out for you
Arnau Abella
@monadplus
- List
def foldMap[A, B](fa: List[A])(f: A => B)(implicit B: Monoid[B]): B

- Free
final def foldMap[M[_]](f: S ~> M)(implicit M: Monad[M]): M[A]

- ApplicativeFree
final def foldMap[G[_]](f: F ~> G)(implicit G: Applicative[G]): G[A]

- Coyoneda
final def foldMap[G[_]](trans: F ~> G)(implicit G: Functor[G]): G[A]
Fabio Labella
@SystemFw
right, easier to see if you add the fa to all cases
Arnau Abella
@monadplus
All of them are traversing a structure, mapping each element to something "combinable" and then combine the elements
Let me re-read everything you have written so far ...

"give me a translation between instructions, and I'll give you a translation between programs "

I am familiar to using Free monads as interpreters of grammars written as GADTs

Fabio Labella
@SystemFw
I actually think it's easier to grasp the idea of "freeness" with free monoids
cause you don't have to worry about GADTs and natural transformations, and emulating higher ranks in scala and so on