实现返回多列表参数中最短列表的Scheme函数时遇到参数数量不匹配错误的解决求助
Let's break down what's going wrong with your current code and fix it step by step:
1. The Root Cause of the Arity Mismatch
Your current function (define (shortest lst) only accepts one single argument, but you're trying to pass multiple lists (like '(1 2), '(2 3 4), etc.) directly as separate arguments. That's why you're getting an arity mismatch error—Scheme expects one argument, but you're giving it four.
To accept multiple arguments, you need to use a rest parameter in your function definition. In Scheme, this is done by adding a dot before the parameter name, like (define (shortest . lists). This lets lists capture all the passed arguments as a single list of lists.
2. Fixing the Fold Logic
Your foldl lambda is comparing elements directly (< e r), but e and r are entire lists, not their lengths. You need to compare the lengths of the lists instead. Also, the initial value #f isn't ideal here—we should start with the first list in the input, then compare each subsequent list to the current shortest one.
Corrected Code
Here's the fixed version that does exactly what you want:
(define (shortest . lists) (if (null? lists) #f ; Handle empty input case, return #f or adjust as needed (foldl (lambda (current-list shortest-so-far) (if (< (length current-list) (length shortest-so-far)) current-list shortest-so-far)) (car lists) ; Start with the first list as initial shortest (cdr lists))))
How It Works
- Rest Parameter:
(shortest . lists)collects all passed lists into thelistsvariable (e.g., calling(shortest '(1 2) '(2 3 4) '(4) '(5 6 7 8))makeslistsequal to'((1 2) (2 3 4) (4) (5 6 7 8))). - Empty Input Handling: The
if (null? lists)check handles cases where no arguments are passed—you can change#fto an error message or default value if needed. - Foldl Logic: We start with the first list as the initial "shortest so far". For each subsequent list, we compare its length to the current shortest's length. If it's shorter, we update the shortest list; otherwise, we keep the existing one.
Testing Your Example
When you call:
(shortest '(1 2) '(2 3 4) '(4) '(5 6 7 8))
The function will:
- Start with
'(1 2)(length 2) as the initial shortest. - Compare to
'(2 3 4)(length 3) → keep'(1 2). - Compare to
'(4)(length 1) → update to'(4). - Compare to
'(5 6 7 8)(length 4) → keep'(4). - Return
'(4)as expected.
Optional: Handling Ties
If you want to return the first shortest list when multiple lists have the same minimum length (which the above code does), you're all set. If you wanted the last one instead, you'd use foldr instead of foldl.
内容的提问来源于stack exchange,提问作者Alex Smith

