我遇到了一个我想了解更多信息以及如何避免的问题。 我有这个代码
len :: (Num r ) => [a] -> r len [] = 0 len xs = 1 + len ( tail xs ) avg :: (Num t) => [t] -> Double avg xs = ( sum xs ) / ( len xs )其中呈现以下错误
len.hs:6:9: Couldn't match expected type `Double' against inferred type `t' `t' is a rigid type variable bound by the type signature for `avg' at len.hs:5:12 In the expression: (sum xs) / (len xs) In the definition of `avg': avg xs = (sum xs) / (len xs)现在,我知道这个错误(感谢irc.freenode.net#haskell)是分割函数的结果
(/) :: (Fractional a) => a -> a -> a但是,我不知道该怎么做。 我的avg功能签名应该与分区操作符怪癖无关(要求Fractional类型类型)。 所以,我仍然想着克服这个问题的正确方法是将它转换成一种类型,它可以使Fractional类型类型化,但我不知道如何,或者即使这是正确的? 有任何想法吗?
I'm having an issue I want to learn more about, and how to avoid. I've got this code
len :: (Num r ) => [a] -> r len [] = 0 len xs = 1 + len ( tail xs ) avg :: (Num t) => [t] -> Double avg xs = ( sum xs ) / ( len xs )Which renders the following error
len.hs:6:9: Couldn't match expected type `Double' against inferred type `t' `t' is a rigid type variable bound by the type signature for `avg' at len.hs:5:12 In the expression: (sum xs) / (len xs) In the definition of `avg': avg xs = (sum xs) / (len xs)Now, I know this error (thanks to irc.freenode.net#haskell) is a result of the division function
(/) :: (Fractional a) => a -> a -> aHowever, I don't know what to do. My avg function signature should have nothing to do with the division opperators quirks (requiring Fractional typeclass). So, I'm left thinking the right way to overcome this is by casting to a type that impliments they Fractional typeclass but I have no idea how, or even if this is right? Any ideas?
最满意答案
我的avg功能签名应该与分区运营商的怪癖无关
这是为什么? 如果你想计算一串整数的平均值,那么你必须在某个点上进行分割,所以你必须将它们从整数转换为你选择的分割支持类型。 仔细看一下Num类( :i Num gnci中的:i Num )揭示了avg类型的一个问题: Num没有足够的方法 - 基本上足以进行添加,乘法和减法。 我不能保证我给avg的号码可以转换为Double 。
如果你输入一个无类型函数来计算平均值,Haskell用最通用的类型进行响应:
Prelude List> :type \x -> sum x / genericLength x \x -> sum x / genericLength x :: (Fractional a) => [a] -> a所以这是avg的正确类型。
你可能会注意到avg [1,2,3 :: Integer]给出了一个类型错误。 您可以通过将参数分别传递给toRational或fromIntegral来toRational ,它们分别将Real和Integral实例用于Integer 。
关于表达式sum [1,2,3] / len [1,2,3] :确实,像1这样的文字数字的类型是Num a => a ,它在任何类型上调用fromInteger ,但是像1/2这样的表达式具有更具体的Fractional a => a类型,如果您询问表达式的类型而不是将其打印出来,则可以看到它。
一些可能有用的东西是:set -Wall in ghci,当你为你选择一个默认类型时会打开许多警告,给出一个线索,即最通用的类型可能不再正确。
My avg function signature should have nothing to do with the division operator's quirks
Why is that? If you want to compute the average of a bunch of Integers, you'll have to divide at some point, so you'll have to convert them from Integers to the division-supporting type of your choice. A close look at the Num class (:i Num in ghci) reveals one problem with the type of avg: Num doesn't have enough methods — basically enough to add, multiply, and subtract. There's no guarantee that the number I give to avg can be converted to a Double at all.
If you enter an untyped function to compute an average, Haskell responds with the most generic type possible:
Prelude List> :type \x -> sum x / genericLength x \x -> sum x / genericLength x :: (Fractional a) => [a] -> aSo that's the correct type of avg.
You might notice that avg [1,2,3 :: Integer] gives a type error. You can get around that by passing the argument to toRational or fromIntegral first, which use the Real and Integral instances for Integer, respectively.
Regarding the expression sum [1,2,3] / len [1,2,3]: It's true that a literal number like 1 has the type of Num a => a, which calls fromInteger on whatever type it turns out to be, but an expression like 1/2 has a more specific type of Fractional a => a, which you can see if you ask for the type of that expression instead of printing it out.
Something that might be helpful is :set -Wall in ghci, which turns on lots of warnings whenever a default type is chosen for you, giving a clue that the most generic type might no longer be correct.
Haskell分配数量(Haskell dividing num)我遇到了一个我想了解更多信息以及如何避免的问题。 我有这个代码
len :: (Num r ) => [a] -> r len [] = 0 len xs = 1 + len ( tail xs ) avg :: (Num t) => [t] -> Double avg xs = ( sum xs ) / ( len xs )其中呈现以下错误
len.hs:6:9: Couldn't match expected type `Double' against inferred type `t' `t' is a rigid type variable bound by the type signature for `avg' at len.hs:5:12 In the expression: (sum xs) / (len xs) In the definition of `avg': avg xs = (sum xs) / (len xs)现在,我知道这个错误(感谢irc.freenode.net#haskell)是分割函数的结果
(/) :: (Fractional a) => a -> a -> a但是,我不知道该怎么做。 我的avg功能签名应该与分区操作符怪癖无关(要求Fractional类型类型)。 所以,我仍然想着克服这个问题的正确方法是将它转换成一种类型,它可以使Fractional类型类型化,但我不知道如何,或者即使这是正确的? 有任何想法吗?
I'm having an issue I want to learn more about, and how to avoid. I've got this code
len :: (Num r ) => [a] -> r len [] = 0 len xs = 1 + len ( tail xs ) avg :: (Num t) => [t] -> Double avg xs = ( sum xs ) / ( len xs )Which renders the following error
len.hs:6:9: Couldn't match expected type `Double' against inferred type `t' `t' is a rigid type variable bound by the type signature for `avg' at len.hs:5:12 In the expression: (sum xs) / (len xs) In the definition of `avg': avg xs = (sum xs) / (len xs)Now, I know this error (thanks to irc.freenode.net#haskell) is a result of the division function
(/) :: (Fractional a) => a -> a -> aHowever, I don't know what to do. My avg function signature should have nothing to do with the division opperators quirks (requiring Fractional typeclass). So, I'm left thinking the right way to overcome this is by casting to a type that impliments they Fractional typeclass but I have no idea how, or even if this is right? Any ideas?
最满意答案
我的avg功能签名应该与分区运营商的怪癖无关
这是为什么? 如果你想计算一串整数的平均值,那么你必须在某个点上进行分割,所以你必须将它们从整数转换为你选择的分割支持类型。 仔细看一下Num类( :i Num gnci中的:i Num )揭示了avg类型的一个问题: Num没有足够的方法 - 基本上足以进行添加,乘法和减法。 我不能保证我给avg的号码可以转换为Double 。
如果你输入一个无类型函数来计算平均值,Haskell用最通用的类型进行响应:
Prelude List> :type \x -> sum x / genericLength x \x -> sum x / genericLength x :: (Fractional a) => [a] -> a所以这是avg的正确类型。
你可能会注意到avg [1,2,3 :: Integer]给出了一个类型错误。 您可以通过将参数分别传递给toRational或fromIntegral来toRational ,它们分别将Real和Integral实例用于Integer 。
关于表达式sum [1,2,3] / len [1,2,3] :确实,像1这样的文字数字的类型是Num a => a ,它在任何类型上调用fromInteger ,但是像1/2这样的表达式具有更具体的Fractional a => a类型,如果您询问表达式的类型而不是将其打印出来,则可以看到它。
一些可能有用的东西是:set -Wall in ghci,当你为你选择一个默认类型时会打开许多警告,给出一个线索,即最通用的类型可能不再正确。
My avg function signature should have nothing to do with the division operator's quirks
Why is that? If you want to compute the average of a bunch of Integers, you'll have to divide at some point, so you'll have to convert them from Integers to the division-supporting type of your choice. A close look at the Num class (:i Num in ghci) reveals one problem with the type of avg: Num doesn't have enough methods — basically enough to add, multiply, and subtract. There's no guarantee that the number I give to avg can be converted to a Double at all.
If you enter an untyped function to compute an average, Haskell responds with the most generic type possible:
Prelude List> :type \x -> sum x / genericLength x \x -> sum x / genericLength x :: (Fractional a) => [a] -> aSo that's the correct type of avg.
You might notice that avg [1,2,3 :: Integer] gives a type error. You can get around that by passing the argument to toRational or fromIntegral first, which use the Real and Integral instances for Integer, respectively.
Regarding the expression sum [1,2,3] / len [1,2,3]: It's true that a literal number like 1 has the type of Num a => a, which calls fromInteger on whatever type it turns out to be, but an expression like 1/2 has a more specific type of Fractional a => a, which you can see if you ask for the type of that expression instead of printing it out.
Something that might be helpful is :set -Wall in ghci, which turns on lots of warnings whenever a default type is chosen for you, giving a clue that the most generic type might no longer be correct.
发布评论