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
Haskell 数字分割的类型声明_Haskell_Types_Sicp - Fatal编程技术网

Haskell 数字分割的类型声明

Haskell 数字分割的类型声明,haskell,types,sicp,Haskell,Types,Sicp,我尝试了所有可能的类型声明,但我甚至无法编译这段代码。诀窍在于为部门处理类型。我试过numa,分数a,Float a等等 我通过删除/函数来隔离问题。此代码编译时完全没有任何类型声明: cube x = x * x * x sum' term a next b = if a > b then 0 else term a + sum' term (next a) next b integral f a b n = (sum' term 0 succ n) whe

我尝试了所有可能的类型声明,但我甚至无法编译这段代码。诀窍在于为部门处理类型。我试过numa,分数a,Float a等等

我通过删除/函数来隔离问题。此代码编译时完全没有任何类型声明:

cube x = x * x * x

sum' term a next b =
    if a > b
    then 0
    else term a + sum' term (next a) next b

integral f a b n = (sum' term 0 succ n)  where
    h = (b - a)
    y k = f $ a + (k * h)
    term k
        | k == 0 || k == n  = y k
        | odd  k            = 4 * y k
        | even k            = 2 * y k

main = do
    print $ integral cube 0 1 100
另一个问题是如何调试这样的案例?Haskell的错误消息没有多大帮助,很难理解类型变量a0不明确或无法推导a1~a

另外,SICP的ex.1.29

更新

最后的答案是:

cube :: Num a => a -> a
cube x = x * x * x

sum' :: (Int -> Double) -> Int -> (Int -> Int) -> Int -> Double
sum' term a next b =
    if a > b
    then 0
    else term a + sum' term (next a) next b

integral :: (Double -> Double) -> Double -> Double -> Int -> Double
integral f a b n = (h / 3) * sum' term 0 (+1) n  where
    h = (b - a) / n'  where n' = fromIntegral n
    y k = f $ a + (k * h)
    term k
        | k == 0 || k == n  = y k'
        | odd  k            = 4 * y k'
        | even k            = 2 * y k'
        where k' = fromIntegral k

main = do
    print $ integral cube 0 1 100               -- 0.25
    print $ integral cube 0 1 1000              -- 0.25
    print $ integral (\x -> 3 * x * x) 1 3 100  -- 26
/仅用于分数类型的实例,整数类型使用quot。您可以使用引号作为使用反勾号的中缀运算符:

h = (b - a) `quot` n
这两种类型是

(/) :: Fractional a => a -> a -> a
quot :: Integral a => a -> a -> a
没有任何类型同时是分数和整数的实例,这就是为什么所有类型签名都不起作用的原因。不幸的是,GHC不知道一个类型不可能是这两个类的实例,因此错误消息不是很直观。不过,您已经习惯了GHC错误消息的样式,它们提供的详细信息非常有用

此外,正如评论中所建议的,我完全同意所有顶级定义都应该给出类型签名,包括main。它使错误消息更容易阅读

编辑:根据下面的评论,看起来您想要的更像是这种类型的签名

cube :: Num a => a -> a

sum' :: (Int -> Double) -> Int -> (Int -> Int) -> Int -> Double

integral :: (Double -> Double) -> Double -> Double -> Int -> Double
您需要使用fromIntegral将h和k中的Int转换为Double。但是,对于这些类型签名,类型错误的可读性至少要高一点。

/仅用于分数类型的实例,对于整数类型,使用quot。您可以使用引号作为使用反勾号的中缀运算符:

h = (b - a) `quot` n
这两种类型是

(/) :: Fractional a => a -> a -> a
quot :: Integral a => a -> a -> a
没有任何类型同时是分数和整数的实例,这就是为什么所有类型签名都不起作用的原因。不幸的是,GHC不知道一个类型不可能是这两个类的实例,因此错误消息不是很直观。不过,您已经习惯了GHC错误消息的样式,它们提供的详细信息非常有用

此外,正如评论中所建议的,我完全同意所有顶级定义都应该给出类型签名,包括main。它使错误消息更容易阅读

编辑:根据下面的评论,看起来您想要的更像是这种类型的签名

cube :: Num a => a -> a

sum' :: (Int -> Double) -> Int -> (Int -> Int) -> Int -> Double

integral :: (Double -> Double) -> Double -> Double -> Int -> Double

您需要使用fromIntegral将h和k中的Int转换为Double。但是,使用这些类型签名,类型错误应该至少更具可读性。

仅供参考,它将是浮动的,因为浮动是一种具体的类型。在这种情况下,我要做的第一件事是写出所有顶级声明的类型。如果我不能弄清楚类型,我会询问ghci,然后尝试了解结果。如果ghci不接受该程序,请删除内容,直到它接受为止。一般来说,这是一个好习惯,因为它有助于更准确地理解程序。是的,我这样做了,它给了我这样的声明:sum':Num a1,Ord a=>a->a->a->a->a->a->a->a->a积分::分数a,积分a=>a->a->a->a,但它对我没有帮助:-@surganov,多练习打字会对你有所帮助。大多数Haskeller最终会在函数之前编写类型,这有助于他们编写函数。GHCi:t是有帮助的,但不能代替理解。开始侧注:如果我没有大错特错的话,succ是来自Enum的,它可能会稍微减慢速度,因为它会在溢出时出错;如果你不需要它,就不要使用它。因为你处理的是数字,所以用+1代替。仅供参考,这将是浮动的,因为浮动是一种具体类型。在这种情况下,我要做的第一件事是写出所有顶级声明的类型。如果我不能弄清楚类型,我会询问ghci,然后尝试了解结果。如果ghci不接受该程序,请删除内容,直到它接受为止。一般来说,这是一个好习惯,因为它有助于更准确地理解程序。是的,我这样做了,它给了我这样的声明:sum':Num a1,Ord a=>a->a->a->a->a->a->a->a->a积分::分数a,积分a=>a->a->a->a,但它对我没有帮助:-@surganov,多练习打字会对你有所帮助。大多数Haskeller最终会在函数之前编写类型,这有助于他们编写函数。GHCi:t是有帮助的,但不能代替理解。开始侧注:如果我没有大错特错的话,succ是来自Enum的,它可能会稍微减慢速度,因为它会在溢出时出错;如果你不需要它,就不要使用它。因为你处理的是数字,所以用+1代替。根据官方文件,quot是向零截断的整数除法,即。E5 QUOTE 2==2,这对于数值计算是不可接受的integrals@surganov单态限制可能是getti
因为您没有类型声明,所以拒绝您。尝试使用/并向所有顶级定义添加类型签名,并将所有变量指定为Float。这是我自己无法解决的问题-添加必要的类型声明以运行此代码。你能帮我吗?你可能想在除法之前用fromIntegral把Int转换成浮点。使用Double,而不是Float,除非你有充分的理由。确保使用::Int约束整型;使用Integer是默认设置,但除非您的整数非常大,否则不是您想要的。学习以这种方式使用类型检查器非常重要。它是Haskell程序员最重要、最强大的工具之一。这需要实践,但它变得非常有用。这也证明了类型签名对于顶级定义的重要性。E5 QUOTE 2==2,这对于数值计算是不可接受的integrals@surganov由于没有类型声明,单态限制可能会影响您。尝试使用/并向所有顶级定义添加类型签名,并将所有变量指定为Float。这是我自己无法解决的问题-添加必要的类型声明以运行此代码。你能帮我吗?你可能想在除法之前用fromIntegral把Int转换成浮点。使用Double,而不是Float,除非你有充分的理由。确保使用::Int约束整型;使用Integer是默认设置,但除非您的整数非常大,否则不是您想要的。学习以这种方式使用类型检查器非常重要。它是Haskell程序员最重要、最强大的工具之一。这需要实践,但它变得非常有用。这也说明了类型签名对于顶级定义的重要性。