定义函数 squarefact::Int -> Int 计算任何正整数 n 的平方阶乘 (n!)^2 == (1 * ...* n)^2

问题描述

我正在尝试定义一个函数,该函数为任何正整数计算其阶乘的平方

(我是 Haskell 的初学者,感谢任何提示或帮助)

我尝试了几种不同的方法,一种我认为可以工作,另一种定义我不明白为什么它不起作用

我认为有效的功能

 squarefact:: Int -> Int
 squarefact 0 = 1
 squarefact n = n * n * squarefact(n-1)

函数我不明白为什么它不起作用:

squarefact:: Int -> Int
squarefact 0 = 1
squarefact n = (n * squarefact(n-1) ) * (n * squarefact(n-1) )

解释和浏览定义的命令将帮助我更好地理解它们,谢谢。

解决方法

等式

squarefact n = (n * squarefact(n-1) ) * (n * squarefact(n-1) )

可以用数学符号重写为

(n!)^2 = n * ((n-1)!)^2 * n * ((n-1)!)^2

但是这个身份是不正确的。右侧包含因数 1,2,....,n-1 四次 次,而不是像左侧那样只有两次。

相比之下,

squarefact n = n * n * squarefact(n-1)

是正确的,因为在双方所有因素都恰好出现两次。

,

阶乘函数可以在 Haskell 中定义为

factorial n = product [1..n]

(其中 product 是计算给定列表中所有数字的乘积的函数。)

因此,

squarefact n = square (factorial n) =
  = square (product [1..n])
  = product [1..n] * product [1..n]
  = 1 * 2 * 3 * ... * (n-1) * n *
    1 * 2 * 3 * ... * (n-1) * n
  = product [1..(n-1)] * n * product [1..(n-1)] * n
  = n * n * square (product [1..(n-1)])
  = n * n * squarefact (n-1)

n=0 ( squarefact 0 /= 0 * 0 * squarefact (-1) ) 的等式重写分解,因此必须将其作为特殊情况处理。