Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C中函数式编程的意外结果_C_Haskell_Functional Programming_Purely Functional - Fatal编程技术网

C中函数式编程的意外结果

C中函数式编程的意外结果,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 =

在试验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 = 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;