Search code examples
purescript

PureScript - Pattern match arrays of unknown length


Is there a way to pattern match arrays of an unknown length in PureScript? As an example, here's how I would do it with a List in Haskell:

addFirstTwo :: (Num a) => [a] -> a
addFirstTwo (x:y:_) = x + y

I tried something similar (using Array a instead of [a]) in PureScript, but got the following error:

Operator Data.Array.(:) cannot be used in a pattern as it is an alias for function Data.Array.cons. Only aliases for data constructors may be used in patterns.

I know I can use Lists in PureScript instead of Arrays, but I'd like to pattern match with arrays. I didn't see how to do this after reading the Array pattern matching section of PureScript by Example.


Solution

  • Array cons patterns have been removed from the language long ago. You can use uncons from Data.Array instead, like so:

    case uncons xs of
      Just {head: x, tail} ->
        case uncons tail of
          Just {head: y, tail: _} -> x + y
          Nothing -> 0
      Nothing -> 0
    

    But beware that unconsΘ(n).

    Alternatively you can use take from Data.Array:

    case take 2 xs of
      [a, b] -> a + b
      _ -> 0
    

    takeΘ(min(n, m)) (in this case m = 2).

    Or even (!!) from Data.Array:

    case xs !! 0, xs !! 1 of
      Just x, Just y -> x + y
      _, _ -> 0
    

    In general lists are more pleasant to work with than arrays are.