Search code examples
opa

How to iterate over the keys in a stringmap?


What I really want to do is iterate over the keys of a stringmap. I am using the new-fangled syntax. I can't find any info on StringMap.iter() so I used the syntax I found somewhere for List.iter(). I don't think the original code actually iterated over the keys, and for now I would settle for iterating over the values if I could get that to work.

The code I have is here: http://pastebin.com/9HB20yzy

I get the following error:

Error
File "test.opa", line 23, characters 1-64, (23:1-23:64 | 472-535)
Function was found of type
(string, 'a -> void), ordered_map(string, 'a, String.order) -> void but
application expects it to be of type
(string -> xhtml), stringmap(item) -> 'b.
Types string, 'a -> void and string -> xhtml are not compatible
Hint:
  Function types have different arguments arity (2 versus 1).

I tried several other methods, but they appeared to be using the old syntax and didn't jive with the compiler. I don't really understand what this error voodoo is telling me, so the question is, how does one use StringMap.iter()? Or iterate over the keys in a StringMap in some other way?


Solution

  • Function types have different arguments arity (2 versus 1) means you try to use a function taking 1 argument, whereas a function with 2 arguments is expected. You iterate on a list through values only, but you iterate on a map through keys and values.

    Then, List.iter or StringMap.iter are mean't to perform side effect (like logging in the console for example). They return no value. This is probably not what you want to do in your code.

    You should use StringMap.fold instead:

    // item is a record of type {string description, string url}
    function render_item(item) {
    <>
      <li>
        <h4>item</h4>
        <a href="{item.url}">{item.description}</a>
      </li>
    </>
    }
    
    function render_index() {
        function f(key, item, acc){
            [render_item(item) | acc]
        }
        <ul>
          { StringMap.fold(f, /mydb/items, []) }
        </ul>
    }