Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Opposite of Codec.invmap would be useful #105

Open
Choc13 opened this issue Mar 1, 2021 · 1 comment
Open

Opposite of Codec.invmap would be useful #105

Choc13 opened this issue Mar 1, 2021 · 1 comment

Comments

@Choc13
Copy link

Choc13 commented Mar 1, 2021

So I find myself writing the following quite a bit:

type VariableName = VariableName of string

module VariableName =
    let value (VariableName x) = x

module VariableNameCodec =
    let ofDomain = VariableName.value
    let toDomain = VariableName

    let encoder = ofDomain >> JsonEncode.string

    let decoder = JsonDecode.string >> Result.map toDomain

    let codec = decoder, encoder    

And then I saw Codec.invmap and assumed that would satisfy me and I could write JsonCodec.string |> Codec.invmap toDomain ofDomain. However invmap works in the other direction, mapping the JsonValue part of the codec rather than the VariableName part of the codec. Or alternatively, the input to the decoder and the output of the encoder.

I think it would be nice to add the following alongside invmap.

let inline contrainvmap f g (decoder, encoder) =
        map (map f) decoder, contramap g encoder

Although I'm not sure the name is quite correct because actually on the decoder it's mapping twice (once through the function and then through the result type it returns) and also because I'm not sure if "contrainvmap" is the correct category theory based name for this thing.

Thoughts on adding this (assuming I've not overlooked something that already exists which does this)?

@gusty
Copy link
Member

gusty commented Apr 18, 2021

I also thought about it, but it turns out it's quite easy to convert the isomorphism into a codec. Here's an example of mapping a codec from Map to list:

(Ok << Map.ofList, Map.toList)  |> Codec.compose c

As you can see, all we have to do is to add OK << to the first function and we have turned an iso-morphism into a codec, so now we can use compose and choose in which order it does compose with other codecs.

But I think your suggestion is still valid, I just wonder if there is a standard name for it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants