Solution (source code)

= Solution

Clamp a nonpositive count to zero. Taking restricts the domain of present indices; dropping translates that domain:
``
take' :: Int -> List a -> List a
take' count (List f) = List query
  where
    k = max 0 count
    query i
      | i < 0 || i >= k = Nothing
      | otherwise      = f i

drop' :: Int -> List a -> List a
drop' count (List f) = List query
  where
    k = max 0 count
    query i
      | i < 0 || i > maxBound - k = Nothing
      | otherwise                = f (i+k)

length' :: List a -> Int
length' (List f) = countFrom 0
  where
    countFrom i = case f i of
                    Nothing -> i
                    Just _  -> countFrom (i+1)
``
For finite length $m$, the first two operations give lengths $\min(k,m)$ and $\max(m-k,0)$, respectively. The length loop reaches the first absent index, namely $m$, so it terminates for a total finite representation. It does not terminate on an infinite represented <sequence>. There is no assumption that an arbitrary stored query <function> takes constant time.