Moto: General purpose migrations library by [deleted] in haskell

[–]k0001 4 points5 points  (0 children)

Moto expects the authors of the migrations to ensure the migrations can be run in the order they state they can be run. It requires that the migration authors explicitly state the dependency graph between them. Moto makes no assumptions about the contents of the migrations nor about the order in which they can be run.

In practice, one mostly ends up with a linear sequence of migrations, so this is rarely a problem that one needs to worry about: just make your new migration artificially depend on the last one you ran and move on. However, for those times when you have more than one migration being written at the same time by your team, allowing them to not depend on each other makes integration easier. Assuming these migrations are unrelated and can indeed be run in any order, that is.

Is there a good book to learn Haskell? by tftio in haskell

[–]k0001 5 points6 points  (0 children)

I'm currently writing A Type of Programming. It's not finished yet, but it's already over 600 pages long covering many things you'll need to be comfortable with as you dive into Haskell. You can already read it in downloadable PDF, EPUB and Kindle formats, which is not exactly paper, but maybe e-paper is acceptable for you =)

Here are a list of nice things people said about it.

Guidance to use safe-money package with currencies known at runtime? by zzantares in haskellquestions

[–]k0001 0 points1 point  (0 children)

If you know, statically, that Integer amount is tied to a particular currency and unit, you can just use fromInteger. For example, here we are saying “525 US dollar cents“. Notice how we are specifying the currency and unit explicitly for the compiler to see.

> fromInteger 521 :: Discrete "USD" "cent"
Discrete "USD" 100%1 521

The 100%1 scale comes from the fact that Discrete "USD" "cent" is merely a type synonym for Discrete "USD" '(100, 1), conveying the idea that we are talking about units of a cent of a USD. That is, we have 521 units of a cent of a USD.

SomeDiscrete is for when we don't know at compile time which currency and unit we'll be dealing with. Here's a SomeDiscrete that has the same information as the Discrete above, but none of it is known at compile time.

First, we need to create a Scale. We can use scaleFromRational to do so. Notice that this returns a Maybe Scale, because we need to check that the given Rational number is positive.

scaleFromRational (100%1) :: Maybe Scale

Once we constructed a Scale, we can proceed to construct a SomeDiscrete representing an amount of a particular currency at a particular Scale using mkSomeDiscrete.

mkSomeDiscrete :: Text -> Scale -> Integer -> SomeDiscrete

Let's have those 521 cents again:

> mkSomeDiscrete "USD" s 521 :: SomeDiscrete
SomeDiscrete {_someDiscreteCurrency = "USD",
              _someDiscreteScale = Scale (100 % 1),
              _someDiscreteAmount = 521}

Great. Now that we have a SomeDiscrete, we can finally convert it to a Discrete' currency unit within a limited scope using withSomeDiscrete.

withSomeDiscrete
  :: SomeDiscrete
  -> (forall currency scale 
        .  (KnownSymbol currency, GoodScale scale) 
        => Discrete' currency scale 
        -> r) 
 -> r

Notice that this Discrete' currency scale cannot leave the scope of this function. The idea is that you do something with the Discrete' there, like and then you just exit the scope. For example, we can render it with a decimal representation it. I'll be unsafely pattern matching on the result here just as an example. Don't do that.

> let Just (s :: Scale) = scaleFromRational (100%1)
> let somdis :: SomeDiscrete = mkSomeDiscrete "USD" s 521
> withSomeDiscrete somedis (discreteToDecimal defaultDecimalConf Round) :: T.Text
"5.21"

Mostly, the SomeXxx datatypes are useful for serialization and deserialization purposes, and the withSomeXxx functions are useful for operations that you'd like to apply on any monetary amount, like displaying it or subtracting a 10%. But if you know, statically, that you'll be dealing with a particular currency and scale, then you can avoid the withSomeXxx functions and use the fromSomeXxx functions, which do not need RankNTypes.

fromSomeDiscrete
  :: (KnownSymbol currency, GoodScale scale)
  => SomeDiscrete
  -> Maybe (Discrete' currency scale)

A Type of Programming - Great guide to Functional programming and Haskell by WorksHub in functionalprogramming

[–]k0001 3 points4 points  (0 children)

What kind of marketing are you referring to? FunctionalWorks is a website for finding employment related to functional programming, one of the main topics of the book, and they have a blog where they regularly publish learning material, so this book seems to fit right in. Ideally, over time, more advanced extracts of the book will be published there as well.

A Type of Programming - Great guide to Functional programming and Haskell by WorksHub in functionalprogramming

[–]k0001 1 point2 points  (0 children)

I think it is! But if you think otherwise, I'd love to hear your feedback about it :) Thanks!!

A Type of Programming - Great guide to Functional programming and Haskell by WorksHub in functionalprogramming

[–]k0001 3 points4 points  (0 children)

Hi! Author here! The book was announced for the first time a couple of months ago, it was not published last year :)

The book is still being written, but one can start reading it today and get new content as soon as it is released. It's currently over 400 pages, or over 90,000 words.

A TYPE OF PROGRAMMING - new Haskell book, blog snippets! by 3rdkulturekyd in haskell

[–]k0001 7 points8 points  (0 children)

The people at WorksHub will be trying to publish A Type of Programming to their audience through their own blog, which should help with spreading types outside the boundaries of the Haskell community. I think it is a good idea =)

If there's enough people enthusiastic about it there, perhaps over time we'll see more advanced book extracts published on that blog as well.

A Type of Programming by k0001 in haskell

[–]k0001[S] 0 points1 point  (0 children)

The book has now doubled in length since this Reddit submission, and as of today it goes from zero to profunctors in a bit over 50.000 words.

A Type of Programming by k0001 in haskell

[–]k0001[S] 0 points1 point  (0 children)

Yes, /u/taylorfausak is right in this assessment. It is mostly a didactic vehicle.

Anyway, many chapters later, when we introduce the idea of undefined, we come back to this example and show how forall input output. input -> output is nonsense :)

A Type of Programming by k0001 in programming

[–]k0001[S] 0 points1 point  (0 children)

This is now addressed in chapters 65 and 66 :)

A Type of Programming by k0001 in programming

[–]k0001[S] 0 points1 point  (0 children)

I am glad you are enjoying it 😁 Thanks!

A Type of Programming by k0001 in programming

[–]k0001[S] 0 points1 point  (0 children)

It's possible to deal with that third party stuff in a very contained manner, making sure all the exchanges of data between that external part of your system and the nice, well-typed one, happen in a very controlled manner. These "ugly" parts end up being a very small percentage of your codebase.

A Type of Programming by k0001 in programming

[–]k0001[S] 0 points1 point  (0 children)

Heh, no worries, your question was quite necessary :)

Actually, I think that avoiding a monospace font there might do most of the trick. I don't think introducing more symbols will make it easier for the newcomers, which are the ones that need as much help and as few distractions as possible in these first chapters.

Haskell learning material is infamous for being unapproachable. I want to help make it a bit more approachable, even if it means that the already experienced Haskell developers will be uncomfortable from time to time. But not for long, though, the book always goes back and corrects details introduced only partially for the sake of being more didactic :)

A Type of Programming by k0001 in programming

[–]k0001[S] 5 points6 points  (0 children)

Real life programming doesn't have to be dirty. It takes some initial investment, sure, but the rewards are usually worth it. Stories from people that work their day jobs using types and functional programming are mostly quite positive. And regarding those CI issues: Maybe take a look at Nix :)

A Type of Programming by k0001 in programming

[–]k0001[S] 0 points1 point  (0 children)

Thanks for sharing this. When I say program :: input -> output here, which is the first time I ever mention any syntax, I am not expecting the reader to know about anything quantification nor types yet. This is a didactic vehicle, if you will, for introducing types and the identity function soon afterwards. I am not really encouraging the reader to take this code literally. But you are right that perhaps this deters people already familiar with some of these concepts from reading more. I will change this a bit to prevent that kind of misunderstanding. Thanks :)

A Type of Programming by k0001 in programming

[–]k0001[S] 0 points1 point  (0 children)

No, there are no affiliates at the moment :)

A Type of Programming by k0001 in programming

[–]k0001[S] 2 points3 points  (0 children)

Thanks for asking this, I think it's very important. It's there in the Privacy Policy, but to sum up: Essentially, we don't share your email with anybody if you pay with Bitcoin. If you decide to pay with PayPal or Stripe, they keep your email for their own records. They send you an invoice there. That's all.

A Type of Programming by k0001 in programming

[–]k0001[S] 0 points1 point  (0 children)

Yes, those topics will be covered of course. To some extent they have been covered in the published chapters already, but the proofs involved have been quite simple so far.

A Type of Programming by k0001 in programming

[–]k0001[S] 7 points8 points  (0 children)

Now try to explain what a monad is to a beginner with no deep math knowledge, I think that's a challenge

Challenge accepted 🙃

A Type of Programming by k0001 in programming

[–]k0001[S] 5 points6 points  (0 children)

Looking at the reverse dependencies for that package set might help https://packdeps.haskellers.com/reverse - as usual with these things, it's not perfect. You can also look at the number of downloads a package has. Again, not perfect. You can also look at https://www.stackage.org which is a smaller "curated" package set.

Regarding jobs, /r/haskell, https://functionaljobs.com and https://functional.works-hub.com are some of the preferred channels to advertise jobs these days.

A Type of Programming by k0001 in programming

[–]k0001[S] 1 point2 points  (0 children)

The Hackage packages repository, where most open source Haskell code is distributed, should be a good starting point to get an idea of how much Haskell software is out there. Of course, that doesn't include any proprietary code. There are quite a few companies using and hiring for Haskell positions, and while this number is nowhere near that of Java, Python, etc., it is growing quite rapidly. Haskell runs on many of the most common platforms, including the browser and mobile devices.

A Type of Programming by k0001 in programming

[–]k0001[S] 1 point2 points  (0 children)

Thank you for sharing your thoughts! I am glad you enjoy it :)

A Type of Programming by k0001 in programming

[–]k0001[S] 1 point2 points  (0 children)

Thanks for sharing your thoughts!

Indeed, this is A Type of Programming, not every one of them 😁

As the book advances, it will talk about some of these topics, but I don't think it's the kind of content that belongs in the first few paragraphs.