There are two base cases for this function. Either the number of elements to be taken runs out (i.e. becomes zero) or the list runs out (i.e. becomes []). The first case is good but the second is bad. In the recursive call we attach the head to the result of taking one less element from the tail.
fun take (_, 0) = [] | take ([], _) = raise Subscript | take (h::t, n) = h::take(t, n-1) handle Overflow => raise Subscript;
Note the excruciatingly familiar final case, again checking for underflow.
Exercise
Construct a drop function with the same type as take. Your drop function should preserve the property for all lists l and non-negative integers n not greater than length l that take(l, n) @ drop(l, n) is l.