content: -- FINAL DOOR STATES ---------------------------------------------------------
  
  -- finalDoors :: Int -> [(Int, Bool)]
  on finalDoors(n)
  
      -- toggledCorridor :: [(Int, Bool)] -> (Int, Bool) -> Int -> [(Int, Bool)]
      script toggledCorridor
          on |λ|(a, _, k)
  
              -- perhapsToggled :: Bool -> Int -> Bool
              script perhapsToggled
                  on |λ|(x, i)
                      if i mod k = 0 then
                          {i, not item 2 of x}
                      else
                          {i, item 2 of x}
                      end if
                  end |λ|
              end script
  
              map(perhapsToggled, a)
          end |λ|
      end script
  
      set xs to enumFromTo(1, n)
  
      foldl(toggledCorridor, ¬
          zip(xs, replicate(n, {false})), xs)
  end finalDoors
  
  -- TEST ----------------------------------------------------------------------
  on run
      -- isOpenAtEnd :: (Int, Bool) -> Bool
      script isOpenAtEnd
          on |λ|(door)
              (item 2 of door)
          end |λ|
      end script
  
      -- doorNumber :: (Int, Bool) -> Int
      script doorNumber
          on |λ|(door)
              (item 1 of door)
          end |λ|
      end script
  
      map(doorNumber, filter(isOpenAtEnd, finalDoors(100)))
  
      --> {1, 4, 9, 16, 25, 36, 49, 64, 81, 100}
  end run
  
  
  -- GENERIC FUNCTIONS ---------------------------------------------------------
  
  -- enumFromTo :: Int -> Int -> [Int]
  on enumFromTo(m, n)
      if n < m then
          set d to -1
      else
          set d to 1
      end if
      set lst to {}
      repeat with i from m to n by d
          set end of lst to i
      end repeat
      return lst
  end enumFromTo
  
  -- filter :: (a -> Bool) -> [a] -> [a]
  on filter(f, xs)
      tell mReturn(f)
          set lst to {}
          set lng to length of xs
          repeat with i from 1 to lng
              set v to item i of xs
              if |λ|(v, i, xs) then set end of lst to v
          end repeat
          return lst
      end tell
  end filter
  
  -- foldl :: (a -> b -> a) -> a -> [b] -> a
  on foldl(f, startValue, xs)
      tell mReturn(f)
          set v to startValue
          set lng to length of xs
          repeat with i from 1 to lng
              set v to |λ|(v, item i of xs, i, xs)
          end repeat
          return v
      end tell
  end foldl
  
  -- map :: (a -> b) -> [a] -> [b]
  on map(f, xs)
      tell mReturn(f)
          set lng to length of xs
          set lst to {}
          repeat with i from 1 to lng
              set end of lst to |λ|(item i of xs, i, xs)
          end repeat
          return lst
      end tell
  end map
  
  -- min :: Ord a => a -> a -> a
  on min(x, y)
      if y < x then
          y
      else
          x
      end if
  end min
  
  -- Lift 2nd class handler function into 1st class script wrapper
  -- mReturn :: Handler -> Script
  on mReturn(f)
      if class of f is script then
          f
      else
          script
              property |λ| : f
          end script
      end if
  end mReturn
  
  -- replicate :: Int -> a -> [a]
  on replicate(n, a)
      set out to {}
      if n < 1 then return out
      set dbl to {a}
  
      repeat while (n > 1)
          if (n mod 2) > 0 then set out to out & dbl
          set n to (n div 2)
          set dbl to (dbl & dbl)
      end repeat
      return out & dbl
  end replicate
  
  -- zip :: [a] -> [b] -> [(a, b)]
  on zip(xs, ys)
      set lng to min(length of xs, length of ys)
      set lst to {}
      repeat with i from 1 to lng
          set end of lst to {item i of xs, item i of ys}
      end repeat
      return lst
  end zip
  