--- Pascal's triangle is the arrangement of binomial coefficients in a triangular array.
--- The rows of the triangle are staggered so that each number can be computed as the
--- sum of the numbers to the left and right in the previous row.
--- The function ;pascal; produces the triangle to a given depth.
module PascalsTriangle;

open import Stdlib.Prelude;

--- Return a list of repeated applications of a given function
scanIterate : {A : Type}Nat(AA)AList A;
scanIterate zero _ _ := nil;
scanIterate (suc n) f a := a :: scanIterate n f (f a);

--- Produce a singleton List
singleton : {A : Type}AList A;
singleton a := a :: nil;

--- Concatenates a list of strings
--- ;concat (("a" :: nil) :: "b" :: nil); evaluates to ;"a" :: "b" :: nil;
concat : List StringString;
concat := foldl (++str) "";

intercalate : StringList StringString;
intercalate sep xs := concat (intersperse sep xs);

showList : List NatString;
showList xs := "[" ++str intercalate "," (map natToString xs) ++str "]";

--- Compute the next row of Pascal's triangle
pascalNextRow : List NatList Nat;
pascalNextRow row :=
  zipWith (+) (singleton zero ++ row) (row ++ singleton zero);

--- Produce Pascal's triangle to a given depth
pascal : NatList (List Nat);
pascal rows := scanIterate rows pascalNextRow (singleton 1);

main : IO;
main := printStringLn (unlines (map showList (pascal 10)));
Last modified on 2023-05-08 11:40 UTC