2

I am trying to simulate a side effect of writing to DB with rescript.

So I want to push the data in an array when calling repository.add. Js.Array.push returns an int, which I do not care about. I would like to force to return unit so that my signature shows unit which lets me know immediately that this function produces a side effect.

Here is the code (and a playground here):

module Person = {
  type entity = {
    firstName: string
  }
  
  type repository = {
    add: entity => unit,
    getAll: unit => array<entity>
  }

  
  let createRepository = (): repository => {
    let storage: array<entity> = []
    
    {
        add: entity => {
          Js.Array.push(entity, storage)  // This has type: int -> Somewhere wanted: unit
          ()         // how to force to return 'unit' there ?
       },
        getAll: () => storage
    }
  }
}
JeromeBu
  • 1,099
  • 7
  • 13

1 Answers1

3

A function will return unit if you return (), as you do. That isn't really the problem here. The reason the compiler complains is that you're implicitly ignoring the value returned by Js.Array.push, which is usually a mistake. You can shut the compiler up by explicitly ignoring it:

let _: int = Js.Array.push(entity, storage)

Edit: I'd also add that you might want to consider using a data structure and API that is more suited for the paradigm. I'd probably use a list and make storage a ref<list> instead, but it depends a bit on what else you're going to do with it.

glennsl
  • 28,186
  • 12
  • 57
  • 75
  • Thanks for your answer. A list may be better, but as I may access the storage with `array.filter.find(...)` (not the head or tail), I thought array where more suited... – JeromeBu Apr 01 '21 at 17:59
  • There's `filter` and `find` for `list` as well. In general I only use arrays if I need either indexed access or direct interaction with bindings that take or return arrays. – glennsl Apr 01 '21 at 18:45