{"action":"created","issue":{"url":"https://api.github.com/repos/gcanti/fp-ts/issues/18","repository_url":"https://api.github.com/repos/gcanti/fp-ts","labels_url":"https://api.github.com/repos/gcanti/fp-ts/issues/18/labels{/name}","comments_url":"https://api.github.com/repos/gcanti/fp-ts/issues/18/comments","events_url":"https://api.github.com/repos/gcanti/fp-ts/issues/18/events","html_url":"https://github.com/gcanti/fp-ts/issues/18","id":213708394,"number":18,"title":"Serialization/deserialization of data types","user":{"login":"gcanti","id":878912,"avatar_url":"https://avatars2.githubusercontent.com/u/878912?v=3","gravatar_id":"","url":"https://api.github.com/users/gcanti","html_url":"https://github.com/gcanti","followers_url":"https://api.github.com/users/gcanti/followers","following_url":"https://api.github.com/users/gcanti/following{/other_user}","gists_url":"https://api.github.com/users/gcanti/gists{/gist_id}","starred_url":"https://api.github.com/users/gcanti/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gcanti/subscriptions","organizations_url":"https://api.github.com/users/gcanti/orgs","repos_url":"https://api.github.com/users/gcanti/repos","events_url":"https://api.github.com/users/gcanti/events{/privacy}","received_events_url":"https://api.github.com/users/gcanti/received_events","type":"User","site_admin":false},"labels":[{"id":561258626,"url":"https://api.github.com/repos/gcanti/fp-ts/labels/discussion","name":"discussion","color":"fef2c0","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":8,"created_at":"2017-03-13T09:09:24Z","updated_at":"2017-03-16T22:19:46Z","closed_at":null,"body":"This is what I get from `Option` now\r\n\r\n```ts\r\nimport { fromNullable } from 'fp-ts/lib/Option'\r\n\r\nconst x = fromNullable(1)\r\nconst y = fromNullable(null)\r\n\r\nconsole.log(JSON.stringify(x)) // => {\"value\":1}\r\nconsole.log(JSON.stringify(y)) // => {}\r\n```\r\n\r\nIn order to behave more like flow-static-land which doesn't change the underline representation when you call `inj / prj`, would be useful a `toNullable` function\r\n\r\n```ts\r\ndeclare function toNullable<A>(fa: HKTOption<A>): A | null\r\n```\r\n\r\nsuch that the pair `inj / prj` is equivalent to the pair `fromNullable / toNullable`. Also both `None` and `Some` could implement the `toJSON` method.\r\n\r\n**Proof of concept**\r\n\r\n```ts\r\nexport class None<A> {\r\n  ...\r\n  toJSON(): null {\r\n    return null\r\n  }\r\n}\r\n\r\nexport class Some<A> {\r\n  ...\r\n  toJSON(): A {\r\n    return this.value\r\n  }\r\n}\r\n\r\nexport function fromNullable<A>(a: A | null | undefined): Option<A> {\r\n  return a == null ? none : new Some(a)\r\n}\r\n\r\nexport function toNullable<A>(fa: HKTOption<A>): A | null {\r\n  return (fa as Option<A>).toJSON()\r\n}\r\n```\r\n\r\nResult\r\n\r\n```ts\r\nconst x = fromNullable(1)\r\nconst y = fromNullable(null)\r\n\r\nconsole.log(toNullable(x)) // => 1\r\nconsole.log(toNullable(y)) // => null\r\n\r\nconsole.log(JSON.stringify(x)) // => 1\r\nconsole.log(JSON.stringify(y)) // => null\r\n```\r\n\r\ndanielepolencic's comment here https://github.com/gcanti/io-ts/issues/31\r\n\r\n> Initially this is what I had.\r\n\r\n> The problem I faced is that - while the .toJSON solves the serialisation - there's no easy way to\r\n> deserialise the data structure.\r\n\r\n> As an example, I'm using a redux-like framework and messages and state are plain objects by definition. When I wrapped my Maybes into classes, I had to > have ser/deser functions all over codebase. This made the code more complicated and bloated.\r\n\r\n> For data types such as Maybe and Either, it makes sense to have the data type as a plain object. In that way there's no need to transform the data into the proper data type."},"comment":{"url":"https://api.github.com/repos/gcanti/fp-ts/issues/comments/287208483","html_url":"https://github.com/gcanti/fp-ts/issues/18#issuecomment-287208483","issue_url":"https://api.github.com/repos/gcanti/fp-ts/issues/18","id":287208483,"user":{"login":"danielepolencic","id":1130499,"avatar_url":"https://avatars1.githubusercontent.com/u/1130499?v=3","gravatar_id":"","url":"https://api.github.com/users/danielepolencic","html_url":"https://github.com/danielepolencic","followers_url":"https://api.github.com/users/danielepolencic/followers","following_url":"https://api.github.com/users/danielepolencic/following{/other_user}","gists_url":"https://api.github.com/users/danielepolencic/gists{/gist_id}","starred_url":"https://api.github.com/users/danielepolencic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/danielepolencic/subscriptions","organizations_url":"https://api.github.com/users/danielepolencic/orgs","repos_url":"https://api.github.com/users/danielepolencic/repos","events_url":"https://api.github.com/users/danielepolencic/events{/privacy}","received_events_url":"https://api.github.com/users/danielepolencic/received_events","type":"User","site_admin":false},"created_at":"2017-03-16T22:19:46Z","updated_at":"2017-03-16T22:19:46Z","body":"I will have a look at (2). It sounds very interesting.\r\n\r\nHowever I still think it brings a lot of overhead. This is very subjective, but this is what I've been thinking so far. The current learning curve for anyone wanting to jump on my codebase right now involves learning:\r\n\r\n- javascript (ok, this is a given)\r\n- typescript\r\n- monads & co\r\n\r\nAs soon as I add something like io-ts and/or babel suddenly my complexity level increases by 2 more technologies. The trade off for me is using the unsafe `JSON.parse` and `JSON.stringify` without needing any extra library. You know already how to use them since they're part of the language.\r\n\r\nAs for Joi, this is used exclusively for APIs and not object models (like in the example your provided above). While there's duplication, this is self contained in specific files that only deal with the APIs. Not ideal, but it's very easy to understand.\r\n\r\nI'm not ready to use tcomb or io-ts. While I see the value, I can't justify the extra complexity of learning and using another tool on top of monads + typescript.\r\n\r\nRe: `compose`. You're right, it's 💩 . Particularly because ts is not able to infer types for curried functions. The pragmatic approach for me is very simple: all functions are _manually_ curried only for the last argument. That covers 80% of my use cases and doesn't require any fiddling with the compiler. From there I use `compose` and most of the time I manually specify the types.\r\n\r\nBeing verbose isn't something I enjoy, but it's the lesser evil.\r\n\r\nI hope this makes sense. I'm not trying to be difficult or go against you. Those are same of the choices I made while diving in the ts and fp world.\r\n"}}
{"actor":{"display_login":"danielepolencic"}}