defmodule Grains do @doc """ Calculate two to the power of the input minus one. """ @spec square(pos_integer()) :: {:ok, pos_integer()} | {:error, String.t()} def square(number) when number < 1 or number > 64 do {:error, "The requested square must be between 1 and 64 (inclusive)"} end def square(number), do: {:ok, 2**(number-1)} @doc """ Adds square of each number from 1 to 64. """ @spec total :: {:ok, pos_integer()} def total do Enum.reduce_while(1..64, {:ok, 0}, fn n, {:ok, sum} -> case square(n) do {:ok, squared} -> {:cont, {:ok, squared + sum}} {:error, error} -> {:halt, {:error, error}} end end) end end