% \insert '../assignment1/List.oz' declare QuadraticEquation Sum RightFold Quadratic LazyNumberGenerator TailRecursiveSum in % task 1 a) proc {QuadraticEquation A B C ?RealSol ?X1 ?X2} Discriminant in Discriminant = B*B - 4.0*A*C RealSol = Discriminant >= 0.0 if RealSol then X1 = (~B - {Sqrt Discriminant})/(2.0*A) X2 = (~B + {Sqrt Discriminant})/(2.0*A) end end % task 1 b) local TestQuad = proc {$ A B C} local RealSol X1 X2 in {QuadraticEquation A B C RealSol X1 X2} {System.show RealSol|[X1 X2]} end end in {System.show 'testing abc'} {TestQuad 2.0 1.0 ~1.0} {TestQuad 2.0 1.0 2.0} end % task 2 fun {Sum List} case List of Head|Tail then Head + {Sum Tail} else 0 end end % task 3 a) fun {RightFold List Op U} % U is the 'default' value of the reduction case List of Head|Tail then {Op Head {RightFold Tail Op U}} else U end end % task 3 c) local RFSum RFLength in fun {RFSum List} {RightFold List fun {$ X Y} X + Y end 0} end {System.show 'are Sum and RFSum the same?'} {System.show ({RFSum [1 2 3 4]} == {Sum [1 2 3 4]})} % % NOTICE: THIS IS COMMENTED OUT BECAUSE IT DEPENDS ON THE `\insert '...'` STATEMENT. % % fun {RFLength List} % {RightFold List fun {$ X Y} X + 1 end 0} % end % {System.show 'are Length and RFLength the same?'} % {System.show ({RFSum [1 2 3 4]} == {Sum [1 2 3 4]})} end % task 3 d) example fold local NonAssociativeOperator in fun {NonAssociativeOperator X Y} {Pow X Y} end {System.show 'are FoldL and FoldR the same under a non-associative operator?'} {System.show {FoldL [1 2 3 4] NonAssociativeOperator 0} == {FoldR [1 2 3 4] NonAssociativeOperator 0}} % note: FoldR is already provided end % task 3 e) Factorial example local Iota Product Factorial in {System.show 'Iota 5 and Factorial 5:'} % same as python's range(1, N+1) -- but in reverse order. % all natural numbers less than or equal to N. % name is borrowed from APL. fun {Iota N} if N > 0 then N|{Iota N-1} else nil end end {System.show {Iota 5}} % multiplies all elements in a list together fun {Product List} {RightFold List fun {$ X Y} X*Y end 1} % U=1 end % factorial is trivially implemented as a fold fun {Factorial N} {Product {Iota N}} end {System.show {Factorial 5}} end % task 4 fun {Quadratic A B C} fun {$ X} A*X*X + B*X + C end end {System.show '3*2^2 + 2*2 + 1 ='} {System.show {{Quadratic 3 2 1} 2}} % task 5 fun {LazyNumberGenerator StartValue} StartValue|(fun {$} {LazyNumberGenerator StartValue+1} end) end {System.show 'should be 5:'} {System.show {{{{{{LazyNumberGenerator 0}.2}.2}.2}.2}.2}.1} % task 6 fun {TailRecursiveSum List} Auxiliary in fun {Auxiliary List Accumulator} case List of nil then Accumulator [] Head|Tail then {Auxiliary Tail Head+Accumulator} end end {Auxiliary List 0} end {System.show 'tail recursive sum of 1 2 3:'} {System.show {TailRecursiveSum [1 2 3]}}