Slices in PureScript

module Main where

import Prelude
import Effect (Effect)
import Effect.Console (log)
import Data.Array (length, slice, updateAt, concat, zipWith)
import Data.Maybe (fromMaybe)

main :: Effect Unit
main = do
  -- Unlike arrays, lists in PureScript are homogeneous but don't have a fixed length.
  -- An empty list is represented as [].
  let s = [] :: Array String
  log $ "uninit: " <> show s <> " " <> show (s == []) <> " " <> show (length s == 0)

  -- To create an array with a specific length, we can use replicate
  let s' = replicate 3 ""
  log $ "emp: " <> show s' <> " len: " <> show (length s')

  -- We can set and get elements just like with arrays
  let s'' = fromMaybe s' $ updateAt 0 "a" s'
  let s''' = fromMaybe s'' $ updateAt 1 "b" s''
  let s'''' = fromMaybe s''' $ updateAt 2 "c" s'''
  log $ "set: " <> show s''''
  log $ "get: " <> show (s'''' !! 2)

  -- length returns the length of the array as expected
  log $ "len: " <> show (length s'''')

  -- We can use concat to append elements to an array
  let s''''' = concat [s'''', ["d"]]
  let s'''''' = concat [s''''', ["e", "f"]]
  log $ "apd: " <> show s''''''

  -- Arrays can be copied using the spread operator
  let c = s''''''
  log $ "cpy: " <> show c

  -- Arrays support slicing with the slice function
  log $ "sl1: " <> show (slice 2 5 s'''''')
  log $ "sl2: " <> show (slice 0 5 s'''''')
  log $ "sl3: " <> show (slice 2 (length s'''''') s'''''')

  -- We can declare and initialize an array in a single line
  let t = ["g", "h", "i"]
  log $ "dcl: " <> show t

  -- PureScript doesn't have a built-in equality check for arrays,
  -- but we can implement one
  let t2 = ["g", "h", "i"]
  log $ if t == t2 then "t == t2" else "t != t2"

  -- Arrays can be composed into multi-dimensional data structures
  let twoD = [ [0]
             , [1, 2]
             , [2, 3, 4]
             ]
  log $ "2d: " <> show twoD

-- Helper function to replicate an element n times
replicate :: forall a. Int -> a -> Array a
replicate n x = map (const x) (0 .. (n - 1))

-- Helper function to create a range of integers
(..) :: Int -> Int -> Array Int
(..) start end = go start where
  go i | i > end = []
       | otherwise = i : go (i + 1)

-- Helper function for array indexing
(!!) :: forall a. Array a -> Int -> Maybe a
(!!) arr i = arr !! i

This PureScript code demonstrates concepts similar to Go’s slices, using PureScript’s arrays. Here are some key differences and notes:

  1. PureScript uses Array for dynamic-sized, homogeneous collections, which is similar to Go’s slices.
  2. PureScript doesn’t have a built-in make function for arrays. Instead, we use a custom replicate function to create an array of a specific length.
  3. The append operation in PureScript is achieved using the concat function.
  4. PureScript uses updateAt for updating specific indices in an array, which returns a Maybe type.
  5. Slicing in PureScript is done using the slice function.
  6. PureScript doesn’t have a built-in multi-dimensional array type, but we can nest arrays to achieve similar functionality.
  7. The == operator in PureScript performs structural equality check for arrays, so we don’t need a separate Equal function.

This example showcases how to work with arrays in PureScript, covering initialization, manipulation, and common operations, mirroring the concepts presented in the original Go example for slices.