6 ms·
I've spent quite a bit of time with Haskell, and all the beginner text like this link are easy to grok, but where I've constantly come up short is trying to wri
by joobus 10y ago
I've spent quite a bit of time with Haskell, and all the beginner text like this link are easy to grok, but where I've constantly come up short is trying to write an app with, for example, a configuration and a database connection. Having multiple levels of Monad transformers just confuses me and I never get anywhere useful. Something like:
App MaybeT IO (StateT IO (EitherT IO Text SomeRecord))
Or something. I haven't figured this out.
- spion 10y agoUse IO for everything at the beginning. Use wai/warp to run an app directly and setup handlers. Use postgresql-simple to send queries. Read the settings object once, then pass it everywhere. You can slowly start writing generic types for your pure code after a while. For example, replace types such as `[t]` with `Functor f => f t` if the only list-related operation done in that function is `map` (fmap). Try to take advantage of the stuff here: https://wiki.haskell.org/Typeclassopedia https://wiki.haskell.org/Typeclassopedia After a while of doing this, you can start looking into how you can write your code in a way to have more generic types, then specialise it for the concrete problems you're solving Finally at this point transformers should become easier and more obvious. Perhaps the first one would be to replace passing the config everywhere with ReaderT. Implementing a few transformers by yourself should help. Start with MaybeT and continue with ReaderT. Tip: `liftIO` magically works but you don't have to always understand how. Maybe also try free monads if transformers seem too annoying!
- atc 10y agoThis is a recommendation I would back for people learning Haskell and don't want to get snagged in the weeds like this. I have been programming in Haskell on and off for a year and eventually got the opportunity to write some REST services in it. It required Servant & PostgreSQL and I didn't generify it too much, just used straight IO. I am now "mature" enough with the language to start generify the API a bit more and depend on things like `MonadIO` instead of direct IO usage, which would also enable better unit testing like those described here: https://lexi-lambda.github.io/blog/2016/10/03/using-types-to-unit-test-in-haskell/ https://lexi-lambda.github.io/blog/2016/10/03/using-types-to... Good luck to GP!
- spion 10y agoI almost forgot; use MVar [1] to keep mutable state around. Its seriously helpful. https://hackage.haskell.org/package/base-4.9.0.0/docs/Control-Concurrent-MVar.html https://hackage.haskell.org/package/base-4.9.0.0/docs/Contro...
- joelthelion 10y agoYou shouldn't need this stuff if you don't want to use it. Just write a few IO functions for interaction with the real world, and pure functions for the rest. I made the same mistake in the past, and I was completely lost. I'm still nowhere near advanced, but sticking to simple stuff and learning slowly I am able to be quite productive now.
- anentropic 10y agoI hit the same problem... I had decided to start with a little toy 'dice rolling' program, but since it involved random numbers I unwittingly got hit with the monad problem up front. It seemed I had two options: either I could pass a seed value around everywhere, or I could lift all my values into monads, necessitating the use of the 'monadic' version of all the operators etc everywhere. I was unable to achieve what you suggest... I could not find a way to keep the 'inner' part of the code as pure functions just expressing simple operations. I submitted here http://codereview.stackexchange.com/questions/114725/my-first-haskell-dice-rolling http://codereview.stackexchange.com/questions/114725/my-firs... I had some useful feedback but no one addressed the "monad pollution" issue. Apart from the different mindset of Haskell (which I found interesting) I struggled with having multiple ways to do everything, how to find the 'right' or monadic version of a particular function or operation, poor docs.
- tome 10y ago> App MaybeT IO (StateT IO (EitherT IO Text SomeRecord)) Ouch! I've written Haskell commercially for the last four years and I've never written (or had to read) anything like this!
- deleted 10y ago[deleted]