C中函数式编程的意外结果
在试验C编程中的函数式风格时,我尝试将下面的Haskell代码翻译成CC中函数式编程的意外结果,c,haskell,functional-programming,purely-functional,C,Haskell,Functional Programming,Purely Functional,在试验C编程中的函数式风格时,我尝试将下面的Haskell代码翻译成C f (0, 0, 0, 1) = 0 f (0, 0, 1, 0) = f (0, 0, 0, 1) + 1 f (0, 1, 0, 0) = f (0, 0, 1, 1) + 1 f (1, 0, 0, 0) = f (0, 1, 1, 1) + 1 f (a, b, c, d) = (p + q + r + s) / (a + b + c + d) where p | a > 0 =
f (0, 0, 0, 1) = 0
f (0, 0, 1, 0) = f (0, 0, 0, 1) + 1
f (0, 1, 0, 0) = f (0, 0, 1, 1) + 1
f (1, 0, 0, 0) = f (0, 1, 1, 1) + 1
f (a, b, c, d) = (p + q + r + s) / (a + b + c + d)
where
p
| a > 0 = a * f (a - 1, b + 1, c + 1, d + 1)
| otherwise = 0
q
| b > 0 = b * f (a, b - 1, c + 1, d + 1)
| otherwise = 0
r
| c > 0 = c * f (a, b, c - 1, d + 1)
| otherwise = 0
s
| d > 0 = d * f (a, b, c, d - 1)
| otherwise = 0
main = print (f (1, 1, 1, 1))
到
#包括
#包括
#定义int常量int
#定义double const double
双f(整数a、整数b、整数c、整数d)
{
如果(a==0&&b==0&&c==0&&d==1)
{
返回0.0;
}
else如果(a==0&&b==0&&c==1&&d==0)
{
返回f(0,0,0,1)+1.0;
}
else如果(a==0&&b==1&&c==0&&d==0)
{
返回f(0,0,1,1)+1.0;
}
else如果(a==1&&b==0&&c==0&&d==0)
{
返回f(0,1,1,1)+1.0;
}
其他的
{
int p=a>0?a*f(a-1,b+1,c+1,d+1):0;
intq=b>0?b*f(a,b-1,c+1,d+1):0;
int r=c>0?c*f(a,b,c-1,d+1):0;
ints=d>0?d*f(a,b,c,d-1):0;
回报(双倍)(p+q+r+s)/(双倍)(a+b+c+d);
}
}
内部主(空)
{
printf(“%f\n”,f(1,1,1,1));
返回退出成功;
}
我期望完全相同的行为,但C程序总是输出0.0。使用f(0,0,1,1)
时,它们都输出0.5,但当数字稍大时,C版本根本不起作用。出什么事了
int p = a > 0 ? a * f(a - 1, b + 1, c + 1, d + 1) : 0;
int q = b > 0 ? b * f(a, b - 1, c + 1, d + 1) : 0;
int r = c > 0 ? c * f(a, b, c - 1, d + 1) : 0;
int s = d > 0 ? d * f(a, b, c, d - 1) : 0;
这里,对f
的递归调用的结果在存储在int变量中时被截断为整数。因此,例如,如果a
是1,而f(a-1,b+1,c+1,c+1)
是0.5
,p
将是0,而不是0.5
,因为不能将0.5
存储在int中
在Haskell代码中,所有变量都是双精度的(或者更确切地说是分数),因此您应该在C版本中执行相同的操作,并将所有变量和参数声明为
double
我认为您需要在C版本中将a、b、C、d和p、q、r、s声明为double
。然后您也可以省略强制转换。我认为参数应该保留为int
s,否则与0
和1
的比较将不起作用。@AntonSavin它们在Haskell中是双精度的,所以为了等价,它们在C中也应该是双精度的。此外,对参数执行的任何操作都不会使与1和0的比较不准确,除非我遗漏了什么。
int p = a > 0 ? a * f(a - 1, b + 1, c + 1, d + 1) : 0;
int q = b > 0 ? b * f(a, b - 1, c + 1, d + 1) : 0;
int r = c > 0 ? c * f(a, b, c - 1, d + 1) : 0;
int s = d > 0 ? d * f(a, b, c, d - 1) : 0;