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
Math Haskell只返回除法的分子(有时)_Math_Haskell - Fatal编程技术网

Math Haskell只返回除法的分子(有时)

Math Haskell只返回除法的分子(有时),math,haskell,Math,Haskell,我有两个职能: calctvd :: [Perk] -> [Perk] -> Perk -> Double calctvd ps fs p = (fromIntegral(tvn) / fromIntegral(points)) :: Double where tvn = calctvn ps fs p points = length $ [i | i <- perkAndPreqs ps p, i `notElem` fs] 本

我有两个职能:

calctvd :: [Perk] -> [Perk] -> Perk -> Double
calctvd ps fs p = (fromIntegral(tvn) / fromIntegral(points)) :: Double
    where
        tvn = calctvn ps fs p
        points = length $ [i | i <- perkAndPreqs ps p, i `notElem` fs]
本质上,第二个函数应该只将第一个函数的值插入列表中。但是,它只插入术语
(fromIntegral(tvn)/fromIntegral(points))的分子。
。我将calctvd中的那一行从积分(points)改为
3/证明了这一点。这样,calctvd仍然返回正确分割的双精度,而updatetvd始终插入3.0的值。如果从updatevd内部调用calctvd,就好像Haskell不计算分母一样

更新1:

然而,这种奇怪的现象似乎依赖于上述两种功能的复杂性。我试着把它分解成一个简单的例子:

testcalctvd :: Double
testcalctvd = fromIntegral(3) / fromIntegral(4) :: Double

testupdatetvd :: Double
testupdatetvd = testcalctvd
但是,testcalctvd和testupdatetvd都返回正确的0.75

更新2:

下面是一个直接从终端开始的示例,使用测试术语
3/从积分(点)

更新3:

下面是perkAndPreqs函数,它可能是罪魁祸首,但我不确定它有多大意义:

--Take a perk and return a list of that perk and all of its pre-requisites
perkAndPreqs :: [Perk] -> Perk -> [Perk]
perkAndPreqs _ NULL = []
perkAndPreqs ps p = [p] ++ perkAndPreqs ps preq
    where
        PerkImpl (_, _, _, _, _, preqstring, _) = p
        preq = perkIdentifier preqstring ps

我的猜测是,当您手动调用
calctvd
时,您传递的
p
参数也不是
ps
参数的第一个元素。但是当从
updatevd
调用
calctvd
时,
p=head ps


我不能确定,因为您既没有向我们展示失败的测试用例,也没有展示
perkAndPreqs
的定义(如果
points
被错误计算为
1
,那么关于为什么可能出现在
perkAndPreqs
)的线索。

请注意:对于
calctvd
函数,你不需要在结尾或任何括号中使用
::Double
。告诉我们你对
perkAndPreqs
@kienjakenobi的定义:显然
calctvd
是一个纯函数。因此,如果从
updatevd
调用时,它会给您意外的输出,那一定是因为您没有给它预期的输入。您可以尝试使用
Debug.Trace
检查传递给它的内容。@kienjakenobi当您自己调用它们时,是否将
p
作为
ps
的第一个元素来调用它们?哈马尔建议使用的是一个很好的方法。@kienjakenobi:在这种情况下,您的函数可以使用
map
重写,因为它对
ps
的每个元素都做相同的事情。执行自己的递归可能容易出错(正如您所注意到的),因此您应该在适当的时候使用高阶函数。
> calctvd initial [] i17
0.6    {This is 3/5, because i17 has 5 points}
> updatetvd initial []
[...3.0...]    {This is just the numerator 3}
--Take a perk and return a list of that perk and all of its pre-requisites
perkAndPreqs :: [Perk] -> Perk -> [Perk]
perkAndPreqs _ NULL = []
perkAndPreqs ps p = [p] ++ perkAndPreqs ps preq
    where
        PerkImpl (_, _, _, _, _, preqstring, _) = p
        preq = perkIdentifier preqstring ps