2024/10/26

Newest at the top

2024-10-26 11:25:40 +0200 <Leary> Not really. Just pull through whatever ExceptT has that you need.
2024-10-26 11:24:42 +0200ash3en1(~Thunderbi@2a03:7846:b6eb:101:93ac:a90a:da67:f207) ash3en
2024-10-26 11:24:34 +0200ash3en(~Thunderbi@146.70.124.222) (Ping timeout: 248 seconds)
2024-10-26 11:24:33 +0200merijn(~merijn@128-137-045-062.dynamic.caiway.nl) (Ping timeout: 248 seconds)
2024-10-26 11:24:31 +0200 <haskellbridge> <tux314159> okay, thanks. but then this kind of runs into the dreaded n^2 instances issue with mtl doesn't it, I have to add every constraint I want to into the deriving
2024-10-26 11:21:44 +0200tomsmedingis afk for a while
2024-10-26 11:20:58 +0200tromp(~textual@92-110-219-57.cable.dynamic.v4.ziggo.nl)
2024-10-26 11:20:44 +0200 <tomsmeding> so yes, the same after peeling off newtype constructors
2024-10-26 11:20:34 +0200 <tomsmeding> it works when your newtype is _coercible_ (as in `Data.Coerce`) to the thing you put after `via`
2024-10-26 11:20:09 +0200 <haskellbridge> <tux314159> I see, this thing works when the instances are equivalent when you peel back the newtype cosntructor?
2024-10-26 11:20:09 +0200 <Leary> via ExceptT e m
2024-10-26 11:20:04 +0200merijn(~merijn@128-137-045-062.dynamic.caiway.nl) merijn
2024-10-26 11:19:36 +0200 <tomsmeding> deriving (Functor, Applicative, Monad) via (ExceptT e m a)
2024-10-26 11:19:12 +0200 <tomsmeding> hm, right
2024-10-26 11:18:54 +0200 <tomsmeding> (in yours, it is not because it's inside an application to 'm')
2024-10-26 11:18:53 +0200 <Leary> Or refer to the transformers with DerivingVia. Which gives you better type roles too.
2024-10-26 11:18:44 +0200 <tomsmeding> the 'a' that is the last type variable of 'App' must also be the last type variable in the type of the field
2024-10-26 11:18:29 +0200 <tomsmeding> write your full stack, then put _that_ inside the newtype
2024-10-26 11:18:17 +0200 <tomsmeding> `newtype App e a = App (ExceptT e IO a)` or something
2024-10-26 11:18:00 +0200 <tomsmeding> ah, the idea is that you put the existing transformers _inside_ your newtype
2024-10-26 11:17:41 +0200 <haskellbridge> <tux314159> oh I was trying `newtype ExceptT' e m a = ExceptT' { runExceptT' :: m (Either e a) } deriving (Functor, Applicative, Monad)` but I guess that's not the correct form?
2024-10-26 11:16:55 +0200 <tomsmeding> https://downloads.haskell.org/ghc/latest/docs/users_guide/exts/newtype_deriving.html#generalising-… , for reference
2024-10-26 11:15:46 +0200 <tomsmeding> it indeed needs to be in the appropriate form
2024-10-26 11:15:34 +0200 <tomsmeding> what is your newtype precisely?
2024-10-26 11:15:25 +0200 <haskellbridge> <tux314159> "couldn't eta reduce enough" or something
2024-10-26 11:15:12 +0200 <tomsmeding> deriving (Functor, Applicative, Monad)
2024-10-26 11:15:06 +0200 <tomsmeding> that's what you have -XGeneralizedNewtypeDeriving for
2024-10-26 11:14:55 +0200 <tomsmeding> separate implementation from interface
2024-10-26 11:14:50 +0200 <tomsmeding> i.e. write your own newtype that internally uses the convenience of mtl stuff, and then write your app in terms of that newtype
2024-10-26 11:14:48 +0200 <haskellbridge> <tux314159> oh I tried that but it wants me to go ahead and define functor/appl/monad for my wrapper and it seems super high-effort for something os simple
2024-10-26 11:14:29 +0200 <tomsmeding> making newtypes around the monads from transformers/mtl is what people generally recommend anyway
2024-10-26 11:14:14 +0200ljdarj(~Thunderbi@user/ljdarj) ljdarj
2024-10-26 11:14:11 +0200 <tomsmeding> make your own newtype around ExceptT?
2024-10-26 11:14:08 +0200 <haskellbridge> <tux314159> but it's more specific so... can I just enable OverlappingInstances xD
2024-10-26 11:13:51 +0200 <haskellbridge> ... long message truncated: https://kf8nh.com/_heisenbridge/media/kf8nh.com/gwoFNkeSYhMaeyAOqJyRqQGR/gklQIOtpBMU (3 lines)
2024-10-26 11:13:51 +0200 <haskellbridge> <tux314159> instance Monad m => MonadFail (ExceptT String m) where
2024-10-26 11:13:29 +0200 <yahb2> \m -> do { Nothing <- m; return "ok" } ; :: MonadFail m => m (Maybe a) -> m String
2024-10-26 11:13:29 +0200 <tomsmeding> % :t \m -> do { Nothing <- m; return "ok" }
2024-10-26 11:13:27 +0200 <Rembane> MonadFail is very good for making do-notation more succinct when only the happy flow is cared about
2024-10-26 11:13:26 +0200 <haskellbridge> <tux314159> actually that's precisely my usecase xD
2024-10-26 11:12:57 +0200 <tomsmeding> for ExceptT, perhaps the reasoning is "ExceptT is for explicit exceptions, and the fail from MonadFail is called also in perhaps unintended situations like partial pattern matches"
2024-10-26 11:12:56 +0200 <Rembane> \o/ Orphan instances ftw! \o/
2024-10-26 11:12:29 +0200merijn(~merijn@128-137-045-062.dynamic.caiway.nl) (Ping timeout: 260 seconds)
2024-10-26 11:12:24 +0200 <tomsmeding> I think for Either the motivation is "there are arguments for an against a MonadFail instance for `Either String a`, so in dispute, let's do nothing"
2024-10-26 11:11:31 +0200 <tomsmeding> (indeed, it has none)
2024-10-26 11:11:16 +0200 <tomsmeding> similarly Either doesn't have the MonadFail instance you might expect
2024-10-26 11:11:04 +0200 <tomsmeding> ExceptT doesn't necessarily have String as the first component
2024-10-26 11:10:41 +0200 <haskellbridge> Hmm is there any reason the MonadFail instance for ExceptT has `fail = ExceptT . fail`? Seems a bit odd, since the whole point of exceptT is to handle these, not bubble them up to the next monad
2024-10-26 11:10:41 +0200 <haskellbridge> <tux314159> think I'll ask here instead then -
2024-10-26 11:10:26 +0200 <tomsmeding> tux314159: for an idea of activity, there are logs https://ircbrowse.tomsmeding.com/browse/lchaskell