DEV Community

Cover image for Encoding HKTs in TS4.1

Encoding HKTs in TS4.1

Michael Arnaldi on October 01, 2020

There have been many attempts at finding valid HKT encodings in TypeScript. Currently the most used and reliable one is implemented by fp-ts. In f...
Collapse
 
beraliv profile image
beraliv

Hey Michael!

Great article, I come back to it already 3rd time, thank you for your time!

Just wanted to let you know that currently links to github.com/Matechs-Garage/matechs-... and github.com/Matechs-Garage/matechs-... are not working

Collapse
 
smolattack profile image
smolattack

Is this the official documentation for effect-ts? Will there be a blog that demonstrates some beginner level CRUD style code? Something like a form that accepts an image on the frontend and a backend API/resolver that persists some data, calls a 3rd party service (e.g., to resize the the uploaded image or send an email, etc...). You know, basic but real-life, used out in the wild type of code.

Collapse
 
mikearnaldi profile image
Michael Arnaldi

Oh by all means it is not supposed to be the official doc, the doc will be created once we have finished porting the api of ZIO 2.0 (planned in a few months from now). Up until the doc arrives this blog series can be an intro to more advanced users. To address beginner friendlier intros we have just launched the "Effect Time" series youtube.com/playlist?list=PLDf3uQL... where every 2 weeks we cover real-word usage.

Collapse
 
smolattack profile image
smolattack

Thanks I'll have a look. I hope you can cover the following in future series (or maybe it could go in the documentation):

  • conventions of effect-ts. For example, what do some common words mean like functions that end with with (e.g., succeedWith), why are new and extends keywords used (having played with fp-ts a bit, I thought those were 'javascript, the bad parts'). Also, generators are weird, why use them (I think it has something to do with addressing limitations of typescript but a full explanation would be great)?

  • Something along the lines of 'Build a blog, the effect-ts way'. So a your usual react, graphql, postgres/prisma deal but using effect-ts to do the business logic, validations, data fetching, etc... I think something like that would be a great intro to some FP basics (Either, Maybe, Tasks, opaque types, Codecs, etc...). If you do decide to create this, please avoid a common trope these days of building it the 'wrong way' and then slowly fixing it throughout the series. Imagine if piano lessons were taught that way (if you didn't finish the full course, you'd just walk away with a bunch of hard-to-break bad habits).

Thread Thread
 
mikearnaldi profile image
Michael Arnaldi
  • the convention of With is still in discussion and may change in the future, it currently identify a lazy version of a function like T.succeedWith(() => 0) vs T.succeed(0) an alternative that we are considering is instead T.succeed(() => 0) and T.succeedNow(0) the reason being it is more common and usually more correct to use the lazy versions (the eager ones are better in some very specific cases for perf but risky to use).

  • new and extends, in this we do not agree with what "the bad parts" are, as a language TypeScript is not Haskell, it is a language that encompass both objects and functions as first-class only focusing on some restricted components limit the possibilities a lot, namely classes are extremely helpful as they are the only typescript construct (apart from enums) that both define a term symbol and a type symbol, namely a class is both a type and a concrete blueprint of an object, this enables for DSLs such as the one exposed in @effect-ts/core/Case that simulates data classes with hash+equals+copy methods.

  • generators this to be honest is trickery and a good degree of magic, the idea was to simulate a monadic do in a way that is native to the language (like an async-await would do for Promise), it turns out to be incredibly powerful as the combination of the generator function with a specialised adapter allows for lifting of a set of natural transformations into the context allowing you to mix and match types, like having a generator of effects that yields Tag, Either, Option, etc out of the box. There is a performance penalty because generators aren't that fast especially if down-level is applied but they are still as fast as async-await (and effect is faster than promise so overall generator+effect is faster than plain async-await) except for multi-shot effects like Array or Stream or Chunk where we have to defensively copy the generator replaying state reconstruction at every element. One of the commonly used patterns is for example to use generators for service construction that usually requires dependencies and flexibility but only runs once at bootstrap time while still use the classic pipe for concrete implementation of procedures.

  • There is some effort ongoing in making some material of the mentioned kind available and we have started a weekly series on youtube where we discuss all things effect with concrete usage and live coding: youtube.com/playlist?list=PLDf3uQL...

Collapse
 
sobolevn profile image
Nikita Sobolev

We are working on the same thing, but in python: github.com/dry-python/returns

I would love to hear your feedback!

Collapse
 
mikearnaldi profile image
Michael Arnaldi

Python... That's unexpected will love to take a look (I would really like to restructure many of the python services I have, definitely see the utility)

Collapse
 
mateiadrielrafael profile image
Matei Adriel

What about this encoding? github.com/pelotom/hkts

It seems way nicer

Collapse
 
mikearnaldi profile image
Michael Arnaldi • Edited

The known limitations listed in the README.md are enough, and unfortunately the issue noted as "it might solve it" doesn't actually solve the problem.

On the same idea another attempt was recently made: github.com/TylorS/hkt-ts and it did solve part of the issues but without ending up with less boilerplate, a small discussion on this: github.com/gcanti/fp-ts/issues/1276.

Collapse
 
mateiadrielrafael profile image
Matei Adriel

Nr 2 was solved by recent ts versions and 3 is a problem with type inference in ts in general (eg: I have similar issues w fp-ts)

Nr 1 can be avoided as long as you don't use the ts equivalent of rank n types (which seems like a fair cost for the simplicity of the implementation)

But fp-ts does it the long way, so what do I know

Thread Thread
 
mikearnaldi profile image
Michael Arnaldi • Edited

Nr 1 can be avoided as long as you don't use the ts equivalent of rank n types (which seems like a fair cost for the simplicity of the implementation).

If that is your objective yes, you can probably simplify it further.

In that encoding I still don't find how to make transformers work like:
github.com/Matechs-Garage/matechs-...

Personally I prefer making the low level implementation complex (as it does not target user-land code) and provide more features that works smoothly.

Collapse
 
johngurin profile image
JohnGurin

Should be

function addOne<URI extends URIS>(F: Functor1<URI>) {
  return (fa: Kind</*F*/URI, number>): Kind</*F*/URI, number> => F.map(fa, (n) => n + 1)
}
Enter fullscreen mode Exit fullscreen mode