You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell中如何提取无限帕斯卡三角嵌套列表的指定列元素

How to Extract the k-th Element from Each Row of an Infinite Pascal's Triangle in Haskell

Hey there! Awesome that you've already got an infinite Pascal's triangle implemented as a nested list—extracting the k-th element from each valid row is totally straightforward, and map is absolutely the right tool for the job. Let's break this down step by step.

First, Clarify Indexing

Haskell lists are 0-indexed, but your example (pascal 4 returning 1,4,10,20…) tells us you're likely thinking in 1-based terms for both rows and elements:

  • The first element 1 is the 4th element of the 4th row (1-based), which translates to the 3rd index of the 3rd row (0-based).
  • The next element 4 is the 4th element of the 5th row (1-based) → 3rd index of the 4th row (0-based), and so on.

Using map with Indexing

Since your infinite triangle is a list of lists ([[Integer]]), we can use map to apply the "get the k-th element" operation to every row. We just need two adjustments:

  1. Convert your 1-based k to a 0-based index (subtract 1).
  2. Drop the first k-1 rows, because those rows are too short to have a k-th element (the n-th row (0-based) has n+1 elements total).

Here's the implementation (assuming your infinite triangle is named pascalTriangle):

pascal :: Int -> [Integer]
pascal k = map (!! (k-1)) $ drop (k-1) pascalTriangle

Let's test this with your example:

  • pascal 4 translates to map (!!3) $ drop 3 pascalTriangle
    • drop 3 pascalTriangle gives us rows starting from the 3rd row (0-based): [1,3,3,1], [1,4,6,4,1], [1,5,10,10,5,1], [1,6,15,20,15,6,1], …
    • map (!!3) extracts the 3rd index from each of these rows: 1,4,10,20,… which matches exactly what you need!

Why This Works

  • Lazy Evaluation: Haskell's laziness means we don't have to compute the entire infinite triangle upfront. map and drop will only generate elements as needed, so the resulting sequence is also infinite and efficient.
  • map is Perfect Here: We're applying the same pure function (indexing into a list) to every element of the triangle list—this is exactly the use case map was designed for.

Alternative: Directly Generate the Sequence (No Triangle Needed)

If you don't need the full triangle anymore, you can skip building it entirely and generate the sequence using binomial coefficient recurrence. The k-th element (1-based) of the n-th row (1-based) is C(n-1, k-1), and we can compute this incrementally without factorials:

import Data.List (scanl')

pascal :: Int -> [Integer]
pascal k = scanl' (\acc n -> acc * (n + k - 1) `div` n) 1 [1..]

This approach is often more efficient than indexing into a pre-built triangle, as it avoids constructing all the extra elements of each row.

Final Notes

  • Add a guard clause if you want to handle invalid inputs: pascal k | k > 0 = ... | otherwise = error "k must be a positive integer"
  • If your original triangle uses 0-based element indexing (e.g., you want pascal 3 to return your example sequence), just adjust the code to use k instead of k-1 in both the index and drop argument.

内容的提问来源于stack exchange,提问作者helloworld

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:36:00