-1

I have some Json that I want to generate Java DAOs from, and would like to do that with the Aeson library. I have already done it in Python using the json module, something like this (snippet/pseudo):

j = json.loads(jsonStr)
def ob(j):
  while (len(j) != 0):
    k, v = j.popitem()
    if type(v) is 'dict':
      ob(v) # then do more stuff
    elif type(v) is 'list':
      arr(v) # then do more stuff
    # etc etc

In Aeson it seems I can "load" the json as above like decode "{\"name\":\"Dave\",\"age\":2}" :: Maybe Object (example from package page) but from there I don't understand what to do, all examples I've seen seem to involve writing data classes, which would defeat the purpose in my case.

I can use fromJust :: Maybe a -> to get fromList [("age",Number 2.0),("name",String "Dave")] :: Object, but from there I'm clueless. If it were a Map (which fromList makes it seem like) I'd do keys then begin traversal as above, but it's not a map.

Thankful for any pointers. Doesn't have to be Aeson I suppose, just seemed like a commonly used library. Thanks.

Erik Vesterlund
  • 481
  • 6
  • 19
  • https://stackoverflow.com/help/how-to-ask –  May 05 '21 at 20:30
  • 4
    Why do you say "it's not a map"? It's an `Object`, and you have [`type Object = HashMap Text Value`](https://hackage.haskell.org/package/aeson-1.5.6.0/docs/Data-Aeson.html#t:Object). – Joseph Sible-Reinstate Monica May 05 '21 at 23:23
  • 1
    What purpose will be defeated by creating an ADT? Include this information above, and not in comment section, please and thank you. –  May 06 '21 at 01:00
  • @MichaelLitchard This purpose: "to generate Java DAOs". To create an ADT I have to manually inspect the Json for names and types. If I wanted to do that I could just write the corresponding Java directly, e.g `class Person { String name; int age; }` for the above. – Erik Vesterlund May 06 '21 at 08:23
  • https://artyom.me/aeson –  May 06 '21 at 16:29
  • @ErikVesterlund What does "manually" (as in "I have to manually inspect") mean? How do you know the fact you are asserting? – Daniel Wagner May 06 '21 at 19:02
  • @DanielWagner I really don't understand what you mean, sorry. – Erik Vesterlund May 06 '21 at 20:27
  • @MichaelLitchard Yes I've read that many times but I don't recognize any of the suggestions there as pertinent to my question. – Erik Vesterlund May 06 '21 at 20:30
  • @ErikVesterlund You say, "To create an ADT, I have to manually inspect the Json for names and types.", but I don't understand that sentence. Can you say what concrete actions you imagine taking when you "manually inspect the Json"? Additionally, once you say that, I predict with high probability that my next question will be something like, "What evidence do you have that you must do that before you can create an ADT?", and so I ask it now to reduce the number of round trips we must do. The answers to these questions will help me write an answer that addresses your misunderstanding. – Daniel Wagner May 06 '21 at 20:31
  • @DanielWagner I still don't understand. Perhaps I'm mistaken, but an ADT for the above Json would be `data Person = Person { name :: String, age :: Int }`. Where do all the words Person, name, String, age, Int come from? I would imagine they come from inspecting the Json, then typing it up. Other than that I don't imagine ADTs will write themselves without a program that reads the Json and generates the ADTs - which, coincidentally, is my original question. – Erik Vesterlund May 06 '21 at 21:07
  • Are there any JSON blobs that would be correct JSON but *invalid* for your DAO goal? If yes, can you describe in English what properties make for valid blobs? If no, why is [`Value`](https://hackage.haskell.org/package/aeson-1.5.6.0/docs/Data-Aeson.html#t:Value) not a suitable ADT already? – Daniel Wagner May 06 '21 at 21:56
  • @David. No, and I don't think I qualified the structure of the Json anywhere. I don't know if `Value` is suitable or not, and I don't know the consequence of that either way. – Erik Vesterlund May 06 '21 at 22:20
  • 1
    @ErikVesterlund Do I understand that what you want to do is write a Haskell program that will read an arbitrary JSON file (where you don't know the structure ahead of time), and output Java code defining classes with a similar structure as was in the JSON file? – Ben May 07 '21 at 03:58
  • 1
    @ErikVesterlund I believe you're getting downvotes and confusion because "I have some JSON and I want to generate Java DAOs" is not a clear description of that, and in the python pseudocode that was attempting to add to your explanation you glossed over the parts that actually generate anything with `# do more stuff`, so it doesn't show any more of your intent than "read some JSON". So if my guess is right, I think you'll get better responses by rewriting the question to be clearer about that. Remember you're not necessarily talking to people who know what "make some DAOs" means as an idiom. – Ben May 07 '21 at 04:03
  • @Ben Correct, although I've already written the logic and trying to translate it to Haskell, mainly how to "extract" parts of a json. You're right that "DAO" is probably not universally known, I just learned it recently myself, but I didn't get questions about that, just rtfm-style responses or seemingly unrelated questions. – Erik Vesterlund May 08 '21 at 08:45

1 Answers1

2

The transliteration of your Python code looks like this:

type X = TypeError (Text "no source Python to copy")

arr :: Array -> X
arr = error "# then do more stuff" (error "no source Python to copy")

ob :: Object -> X
ob j = error "# then do more stuff" (val <$> j)

val :: Value -> X
val (Object o) = ob o
val (Array a) = arr a
val _ = error "# etc etc"

But this is very unidiomatic. I encourage you to say more about what computation you want to perform, rather than asking how to mimic some trivial skeleton code from another language. Different beasts have different skeletons.

Daniel Wagner
  • 145,880
  • 9
  • 220
  • 380
  • `val` looks great, I'll look into using that, thanks! As for computation, it's really only "generate Java DAOs", or Haskell adts, or scala case classes, or what have you. So `"foo": 1` would yield `int foo`, `"foo": [ ... ]` would yield `List foo` for some `T`, etc. – Erik Vesterlund May 06 '21 at 22:31
  • @ErikVesterlund What would `{"foo": {"bar": 1}}` yield? – Daniel Wagner May 06 '21 at 23:07
  • Objects should generate classes, is that what you want to know? Recall that the question is not "how build java from json", it's how step through the json, how to deconstruct, in the case of Aeson, a `Value`, which you answered in this answer. – Erik Vesterlund May 08 '21 at 09:06