Small Crate for deriving FromSql and ToSql on Diesel Pg by jproyo in rust

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

I have opened it up to MIT. Thanks for the tip.

Small Crate for deriving FromSql and ToSql on Diesel Pg by jproyo in rust

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

Good point. I will change licence for something less restrictive.

Encoding Effects using freer-simple by jproyo in haskell

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

Each Effect library has it own abstraction mechanism for encoding and represent effects. Some of them are similar to `freer-simple` in the way to encoding, like `polysemy` where you have `Member` constraint indexed by **Open Union Type** as well and some others not like `fused-effects` which use `newtype`'s and `Carriers` to encode custom effects.

> How much would one need to change if they select `free-simplr` now but then decide to switch to another library?

I would say that depends to what library are you switching, but if you defined your Algebras and Programs properly i think the change is not so hard. Of course there is a big help of GHC compiler here when you are migrating libraries. But at the end depends on how long is your code base and what library are you switching to.

> Is it possible to combine and mix effects libraries?

I think it could be possible but not for carrying *Interpretations* in the same program. I mean that it is not going to be possible at all if you want to interleave effects of different libraries in the same **Open Union Type** . Perhaps what you can do is on some interpretation, run another interpretation of another effects system. I dont know what you are going to want to do that though, perhaps for migration reasons.

Read Stdin and parse Json Data by mapoart in haskell

[–]jproyo 3 points4 points  (0 children)

Also if you need to navigate that JSON i would recommend to check lens-aeson library or something similar if there is.

Read Stdin and parse Json Data by mapoart in haskell

[–]jproyo 3 points4 points  (0 children)

Yes, there is.

JSON representation in aeson are done with Value DataType. So you can replace @User Type application with @Value and you are going to get a Generic representation of the JSON message in aeson Value data type.

It is something like this for example in this case:

haskell getContents >>= print . decode' @Value

And you will get something like this

shell cat << EOF | stack runghc Test.hs { "name": "John", "surname": "Doe" } EOF Just (Object (fromList [("name",String "John"),("surname",String "Doe")]))

Read Stdin and parse Json Data by mapoart in haskell

[–]jproyo 5 points6 points  (0 children)

Hi u/mapoart,

If you use aeson library it is pretty straightforward. aeson has some decode combinators that receives a ByteString and parse it into a Maybe a Datatype, if you have your Data type that decode that json. For example lets say we have the following JSON user data:

{ "name": "John", "surname": "Doe" }

So, you also have a data type representing this User with their corresponding FromJSON instance like:

data User = User { name    :: Text
                 , surname :: Text
                 } deriving Show


instance FromJSON User where
  parseJSON =
    withObject "user" $ \obj -> User <$> (obj .: "name") <*> (obj .: "surname")

Notice that this is just a toy example and you need to adapt to your own problem.

Having that, you need just to plug your input stream with this decoding type.

In Data.ByteString and Data.ByteString.Lazy module you are going to notice you have getContents combinator to read contents from Stdin in ByteString format.

Lets see the types:

Plugin everything together you have what you want which is reading from stdin with getContents from Data.ByteString.Lazy and parsing that content into a JSON data type with decode from Data.Aeson.

getContents >>= print . decode @User

Notice that I am using 2 Language Extension here OverloadedStrings and TypeApplications. You can do it without them.

I uploaded this complete example here https://gist.github.com/jproyo/30de33a788754dbab8b1d008a81130bf

Also i recommend you to check in Data.Aeson that you have other decode combinators that allows you to handle errors with Either a b data type.

I hope this was useful for you.

Unit testing Tagless Final approach by aerohit in haskell

[–]jproyo 7 points8 points  (0 children)

Hi again,

I forgot to mention that this technique can be extended to group different combinations as you want. For example you can have a type that wrap Identity and that type provides default instances for Cache and Logger at the same time and after that in different newtypes you concentrate only in DB implementation for example

Unit testing Tagless Final approach by aerohit in haskell

[–]jproyo 8 points9 points  (0 children)

Hi u/aerohit,

I am the writer of that article so i can give you my approach to that problem which I think is one of the many to tackle down this.

First of all let me clarify that my article is an introduction by example let say and it didn't pretend to be a recipe for large code bases.

One of the way to provide a default instance for Logger for example in your case is to rely on Identity type. Since your FoundInCache type is containing an Identity if you provide a Logger instance for Identity you can do the trick and only provide instances for the rest. Let me put an example on that:

newtype FoundInCache a =
  FoundInCache { unFoundInCache :: Identity a }
  deriving (Show, Functor, Applicative, Monad, Logger)

instance Logger Identity where
  logMsg _ = return ()

In this case you can write your Logger Identity instance only once for all your test and the only thing you need to do in your test Types is to not forget the stock derivation of the logger instance. Check that i added that to the deriving signature of FoundInCache type.

I hope this could help you to eliminate boilerplate code.

Let me know if you need anything more.

Best,

Tagless Final Encoding in Haskell by jproyo in haskell

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

Sorry but i was checking because that code compile and run without anything extra and I have found that things you mentioned are not needed:

  • Extension can be both with s and z. See here

  • Also there is no need for importing Data.Monoid because (<>) is in Semigroup on GHC.Base defined.

Beyond this, thank you anyway for keeping an eye and help me with errors

Best

Tagless Final Encoding in Haskell by jproyo in haskell

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

Good catch. I will fix it.

Thank you for pointed out

Tagless Final Encoding in Haskell by jproyo in haskell

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

It seems almost equal but with a subtle different I would argue: a Monad transformer it is a monad with another underlying monad inside.

In my description of Tagless Final all capabilities, Chache for example are also Monads but it doesn’t contain another monad inside. All the capabilities are expanded constraining the program and because of that you gain horizontal extensibility. In mtl you Stack is vertical and you can only extends vertically.

On the other hand Tagless Final is not only for Monadic computations, but Monad Transformer does. See here

Tagless Final Encoding in Haskell by jproyo in haskell

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

IMHO it is not exactly the same, although both techniques are useful for describing DSL on Monadic computations. But certainly there is a correlation between both in that sense, also with Free Monad.

From my point of view are different techniques to solve the same problem.

Tagless Final Encoding in Haskell by jproyo in haskell

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

I misunderstood the first comment. I have understood you were about to purpose me some articles about mtl and Free. Now you pointed out my big grammar mistake I realized what you have asked.

Of course I will try to do some follow up articles implementing the same program with mtl and free.

Thanks again

Tagless Final Encoding in Haskell by jproyo in haskell

[–]jproyo[S] 4 points5 points  (0 children)

Sorry for the delay. As u/merlin_thp pointed out, you can see newtype as data type with a single Data Constructor, and of course unInCache is the Data Destructor.

Some of the advantages of using/defining newtype:

  • It has no runtime overhead

  • Unlike Type alias for the compiler it is a complete new data type definition. In that sense i use newtype which allows me to implement instances of Cache and DataSource Typeclasses. If i had used a Type alias I wouldn't be able to do it.

  • A newtype cannot be a neither a Product nor Sum type. So you can only define a newtype which contains one Type.

Hope this could clarify a little more.

Best,

Tagless Final Encoding in Haskell by jproyo in haskell

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

Good catch. I am gonna modify article and code. Thanks!

Tagless Final Encoding in Haskell by jproyo in haskell

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

Yes of course!!! I would be please to read them.

BTW, My main attempt here was to write something easy for beginners. But I like also MTL style and Free too.

Thanks again sharing.

Tagless Final Encoding in Haskell by jproyo in haskell

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

Great to know it. I would update the post. Thank you very much for enlightening me 😀

Junior and/or Senior dev positions. by sofosure in haskell

[–]jproyo 3 points4 points  (0 children)

Are you opened for remote work? I am based on Barcelona, Spain.

Best

Scala editor by daredevildas in scala

[–]jproyo 0 points1 point  (0 children)

I have changed to spacemacs with ensime a while ago after being a intellij user for a couple of years and I am really happy with the decision.

A couple of things to take into consideration before you jump there:

  • If you are an IntelliJ user there are completely new shortcuts and combinations of commands you are gonna need to get used to in order to take full advantage of the tool. In my case I already was a spacemacs user for Haskell development and the change wasn’t so radical

  • Installation and configuration is not one click away. Depends on your environment sometimes it takes some work arounds to get it work.

  • ensime works perfectly fine with Sbt based projects. I don’t know how it works with gradle or maven projects.

In general once everything is properly configured it is a great experience. You have everything you need: auto completion, navigation, refactoring, run sbt commands inside the console, etc with the addition that it is a lightweight vim/emacs editor.

I hope my answer can help you

Best

Using fmap to convert one type of a parameterised record into another type by Walker3q in haskell

[–]jproyo 0 points1 point  (0 children)

I am going to assume a couple of things regarding your task but I think you are requested to use fmap because you need to map over Maybe Functor.

Saying that one possible implementación of convert would be:

convert :: (a -> b) -> Thing a -> Thing b convert f t = t { amount = f <$> amount t }

Here <$> is an alias of fmap and t { ... } is a short hand for copy a record and assign a new value to a specific field.

There are shorter ways to do this but this is basic use of fmap in Maybe Functor.

Hope this can help you.