Hacker News new | ask | show | jobs
by dmjio 3244 days ago
If decoding json in Elm is considered hard, I'd recommend checking out miso (https://github.com/dmjio/miso), a Haskell re-implementation of the Elm arch. It has access to mature json libraries like aeson for that sort of thing, along with mature lens libraries for updating your model. Here's an example of decoding json with GHC.Generics using typeclasses. https://github.com/dmjio/miso/blob/master/examples/xhr/Main....
9 comments

You don't need to switch a whole language because of JSON decoding. There are many tools that exist to aid you write JSON decoders in Elm. The language is not just about the architecture -- you can implement the architecture in any language, as Redux has proven. What people like about Elm is the compiler and design philosophy that radiates through the entire community. Switching to Haskell won't give you that, as the Haskell community has different priorities.

Here are some JSON tools for Elm:

- json-to-elm http://json2elm.com

- swagger-elm https://github.com/ahultgren/swagger-elm/

- elm-graphql https://github.com/jahewson/elm-graphql, https://github.com/jamesmacaulay/elm-graphql

- elm-export https://hackage.haskell.org/package/elm-export

Oh, this is awesome, json2elm really helps :) thanks, didn't know about it.
No problem! Glad you found it useful :) It's not perfect by any means, but it's not meant to be.
Yeah right, just to jumpstart the effort, especially when there are a lot of entities.
I am kinda waiting for Purescript to mature a tiny bit more in this regard, because it seems that they have something special brewing there, with their polymorphic record type and interesting take on type-level programming.

Because this [1], even though it seems to be just a experiment so far, looks really good.

I.e: doing

type MyTestStrMap = { a :: Int , b :: StrMap Int }

and then just calling

let result = handleJSON """ { "a": 1, "b": {"asdf": 1, "c": 2} } """

let newResult = doSomething (result:: Either MultipleErrors MyTestStrMap))

is kinda all I ever wanted in these haskell inspired languages?

[1] https://github.com/justinwoo/purescript-simple-json/blob/mas...

This is very cool. The example apps are relatively slow to load compared to the equivalent in some other frameworks (my favorite is Mithril for an idea of how small/fast these can get).

Was wondering whether it might be a slow server, but the app.js for the TodoMVC appears to be over a megabyte (1.21 MB, have a 4000 line Mithril app which is 500k uncompressed). What's up with that?

Can you give exact numbers and a testing method of how you tested and determined it is slow?
The router example on Github loads ~1.5 MB of JS files. Mithril's entire framework is 8kb gzipped (including a router).
ghcjs is a pretty heavyweight environment. It's actually translating the compiled core IR from GHC into JavaScript, and including a port of GHC's runtime system.

It can run basically any Haskell library. That includes the ability to run multithreaded Haskell code -- the JS RTS includes a scheduler. You also get Software Transactional Memory. Lazy evaluation works just as usual -- and so on.

The tradeoffs become worth it when you have a sufficiently valuable base of Haskell code that you want to run in the browser, and when your users aren't very constrained by page load time. Say, if you have some complicated tricky logic that you don't want to rewrite in another language, but you want to use it in your web app.

Aeson is SLOOW compared to 'JSON.parse' + GHCJS ffi. You lose a bit of correctness (JSON.parse can decode numbers only to the JS precision, ie. 53bits, while Aeson supports arbitrary precision through Scientific), and ability to decode streams in constant memory. But these are features which you most likely don't need in a web app.
>> Here's an example of decoding json with GHC.Generics using typeclasses.

>> https://github.com/dmjio/miso/blob/master/examples/xhr/Main....

There’s no reason to use genericParseJSON here, you can just write “instance FromJSON APIInfo”. Or leave the instance declaration as it is and safely rename your record fields to e.g. currentUserUrl instead of current_user_url.

The purpose of the camelTo function is to convert “camelCaseExample” into e.g. “camel_case_example” by passing ‘_’ as the first argument. But the APIInfo data structure already uses record fields with underscores in them.

There's also Fable-Elmish[1], which can be used with Fable[2], which is an F#-to-JS compiler.

[1] https://fable-elmish.github.io/elmish/

[2] http://fable.io/

To add to the other comments:

https://github.com/tiziano88/elm-protobuf

This looks really promising. Do you use it in production anywhere? Do you have any comparison of features with Elm?
Decoding json, the one most important format of the web, is hard in elm, a language supposedly designed for the web? I'm glad I didn't give it a try.