Integrated Dynamics

Integrated Dynamics

63M Downloads

How to implement "parameterized" or "reversed" mapping operator?

zjuwyz opened this issue · 4 comments

commented

Issue type:

  • ❓ Question

Question:

Currently I'm doing an automation of Roost mod. This mod adds lots of chicken items, and each of them has three properties stored in its NBT: Strength, Gain, Growth, which are integers ranges from 1 to 10. I'd like to build an operator which takes an item as input and output a list of three integers showing these property values. That is Item->[Int].

The NBT part is easy, I've successfully built an operator with format String->Item->Int to extract a property value of the input item correspondinng to the given property name. Then I built a string list ["Strength", "Gain", "Growth"]. My plan is to "map" the operator onto this string list to get the integer list I want.

Well, operator map failed this case. Map, as we all know, has the format (a->b)->[a]->[b]. However, in this case, the map I need is somehow "parameterized", with format (a->c->b)->[a]->c->[b], where a is String, b is Int, and c is Item, the "parameter" must remained uncurried.

My FP knowledge is poor, so after thinking for a long time, I still had no idea how to deal with it. Then I tried for some workaround. If I apply the origional map to the operator a->c->b, I'll get (a->c->b)->[a]->[c->b]. Well, [c->b] seems close to my goal c->[b]. But after thinking for a while, I realized [c->b]->c->[b] is something like a "reversed" map, where you have a list of operators to map with, rather than a list of inputs to map onto. Unfortunately, this seems equally difficult to me. Still I have no idea what to do.

I tried to find some solution, but I even don't know which keyword to google with. I looked through the issue page and ftb reddit, but found nothing helpful.

Am I thinking in the right way? What should I do next? I appreciate it for any solutions or guidence.

commented

@zjuwyz I happen to be working on the same problem: evaluating chickens via integrated dynamics. I was taking a different approach and your question helped me figure out some things.

To answer your question, you'll need to make use of apply, creating cards as in:

  1. Operator with NBT NBT Value Integer
  2. NBT() (for the argument, use a card representing the Item you're trying to read)
  3. apply with 1. and 2.
  4. List containing the strings for the NBT keys
  5. map with 3. and 4.

apply proxies another operator, but with that operator's first argument bound to some value ahead of time. (There's also apply2 and apply3 for binding the first two and three arguments. Additionally, there's flip for creating a proxy that transposes the first two arguments.)

commented

@zjuwyz I don't think Integrated Dynamics has the capability. It's not Turing complete on its own and doesn't have the necessary list evaluator (something that can take a list of ops and apply the same value to each).

You can have dynamic item input but you'd have to be broader on what's considered an input. For example, if you use a slot in any inventory as a kind of variable containing an item, step 2. would be extended to read that slot and extract the NBT data. Changing out the item in the slot would automatically change out the results. The whole thing can be extended to generate a list of results from an inventory.

RFTools Control is Turing complete but doesn't grant the ability to read individual NBT tags. For my own build, the plan is to use Integrated Dynamics to read the chickens and RFTools to process them.

commented

@zjuwyz I happen to be working on the same problem: evaluating chickens via integrated dynamics. I was taking a different approach and your question helped me figure out some things.

To answer your question, you'll need to make use of apply, creating cards as in:

  1. Operator with NBT NBT Value Integer
  2. NBT() (for the argument, use a card representing the Item you're trying to read)
  3. apply with 1. and 2.
  4. List containing the strings for the NBT keys
  5. map with 3. and 4.

apply proxies another operator, but with that operator's first argument bound to some value ahead of time. (There's also apply2 and apply3 for binding the first two and three arguments. Additionally, there's flip for creating a proxy that transposes the first two arguments.)

Thank you for your suggestion, but I'm afraid this is not what I want. Sorry, I should have made it clearer.

Definitely your method can work. After step 3, the operator a->c->b is simplified to a->b, since c, known as Item, is curried during apply operation. Then the case fall back to default map situation (a->b)->[a]->[b]. but in this way the result is bounded to a specific item card. The difference is, the operator I want is reusable. It can be applied onto many different item cards and get different outputs. In your way you'll need to use one map operator for each item card. That's why I bolded the "parameter" must remain uncurried.

Actually I have an ambitious plan: automating the whole Roost mod from end to end, i.e. to produce every type of chicken, one stack each, with full properties, only given the initial twelve chicken pairs , enough seeds, and the parent list maually pasted from the chicken mod's json. So as you can imagine, I will use this property-extracting operator many many times. So reusability is really important.

At this point, I'm not just seeking for a solution for this specific question, but curious about how to deal with similar situation. I know how to program in C++, I've taught myself some haskell (not that useful I'm afraid, or I wouldn't have opened this issue, but at least it makes me feel ok with this type system). I know I'm given infinite possibility (Turing complete, to be exact), but when I'm programming in ID, I always feel disconcerted and powerless while digging into NBTs, Lists, or any complicate, compounded operations. I'm always struggling to find a clear route from basic ID operators to any high-level ideas I come up with, and sometimes I just simply don't know how to do even after hours of thinking. This is really frustrating.

I guess this problem, or something similar to this, will often occur during complex large-scale automation construction and ideas like "parameterized map" should have a lot of use case and should have been discussed completely. I really appreciate it if someone can give me some enlightenment, or a link to these discussion.

Anyway, thank you again for your detailed solution.

commented

@zjuwyz I don't think Integrated Dynamics has the capability. It's not Turing complete on its own and doesn't have the necessary list evaluator (something that can take a list of ops and apply the same value to each).

You can have dynamic item input but you'd have to be broader on what's considered an input. For example, if you use a slot in any inventory as a kind of variable containing an item, step 2. would be extended to read that slot and extract the NBT data. Changing out the item in the slot would automatically change out the results. The whole thing can be extended to generate a list of results from an inventory.

RFTools Control is Turing complete but doesn't grant the ability to read individual NBT tags. For my own build, the plan is to use Integrated Dynamics to read the chickens and RFTools to process them.

Thank you very much for your advise! Now I see I was thinking in a way which is too idealism, and somehow stubborn and limited. Your advice is really helpful.