Quantcast
Channel: ReScript Forum - Latest posts
Viewing all articles
Browse latest Browse all 1751

Guidance for nested data types

$
0
0

The core principles of functional programming are immutability and separation of code and data.

The most common and idiomatic way to apply this in rescript is with the following module architecture: a main type t that ‘tracks’ the state and that can be abstract in its interface file and functions to interact with this type that return a new state instead of mutating their input:

module Terminal: {
  type t
  type direction = Up | Down | Reset
  let make: (~height: int=?) => t
  let clear: t => t
  let echo: t => t
  let move: (t, ~direction: direction) => t
  let updateCurrentCommand: (t, string) => t
  let getCurrentCommand: t => string
  let getDisplayedLines: t => array<string>
} = {
  type t = {
    content: array<string>,
    currentCommand: string,
    position?: int,
    height: int,
  }

  type direction = Up | Down | Reset

  let make = (~height=10) => {
    content: [],
    currentCommand: "",
    height,
  }

  let clear = t => {...t, content: [], position: ?None}

  let echo = t => {
    ...t,
    content: [...t.content, t.currentCommand],
    currentCommand: "",
    position: ?None,
  }

  let move = (t, ~direction) => {
    ...t,
    position: ?{
      let length = Array.length(t.content)
      let position = t.position->Option.getOr(length)
      switch direction {
      | Up => Int.clamp(~min=t.height, position - 1)->Some
      | Down =>
        let position = position + 1
        position > length ? None : Some(position)
      | Reset => None
      }
    },
  }

  let updateCurrentCommand = (t, currentCommand) => {...t, currentCommand}

  let getDisplayedLines = ({content, height, ?position}) => {
    let length = Array.length(content)
    let position = position->Option.getOr(length)
    content->Array.slice(
      ~start=Int.clamp(~min=0, position - height),
      ~end=Int.clamp(~min=position, height),
    )
  }
  let getCurrentCommand = ({currentCommand}) => currentCommand
}

Playground link (do not forget to enable Auto-run to try it live)

There should be more posts and books around how to architect your code idiomatically in rescript, meanwhile you can read books that focus on functional programming in general and especially the ones that use “pragmatic” functional programming languages like OCaml/F#.


Viewing all articles
Browse latest Browse all 1751

Trending Articles