Haskell fromIntegral-类型混淆 [英] Haskell fromIntegral -- type confusion

查看:222
本文介绍了Haskell fromIntegral-类型混淆的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在经历真实世界Haskell",并且正在做随之而来的练习.

I am just going through "Real World Haskell" and I am doing the excercises that come along with it.

我注意到我认为很奇怪的东西.

And i noticed something that i think is odd.

以该功能为例:

myAverage :: (Fractional a) => [a] -> Maybe a myAverage [] = Nothing myAverage xs = Just $ (mySum xs) / (fromIntegral $ myLength xs)

myAverage :: (Fractional a) => [a] -> Maybe a myAverage [] = Nothing myAverage xs = Just $ (mySum xs) / (fromIntegral $ myLength xs)

(/)函数需要两个参数,它们是Fractional的实例. myLength返回一个Int,所以我按我所告诉的那样使用the fromIntegral函数.

The (/) function wants two arguments that are instances of Fractional. myLength returns an Int so i use the fromIntegral function as i have been told.

但是fromIntegral仅保证返回的值将是Num的实例.

But fromIntegral only garantees that the returned value will be an instance of Num.

在这种情况下,为什么Num也包含" Fractional的实例. Fractional是否更具体?

Why does Num also "include" an instance of Fractional in this case. Isn't Fractional more specific?

为什么编译器不会抱怨我返回类型中只有一个Num而不是适当的" Fractional.

Why doesn't the compiler complain that i have just a Num from the return type and not a "proper" Fractional.

为什么我不能直接使用Int,它也是Num的实例,不是吗?

Why can't i use the Int directly, it is also an instance of Num, is it not?

在调用mySum的情况下,我明白了.它需要一个Num的列表,但是我要给它一个Fractional的列表(它们也是Num的列表,因为它们是从中派生的).返回类型具有相同的类型,这可以从类型注释中看出(请参见下文):Fractional

In the case of calling mySum i get it. It takes a list of Nums but i feed it with a list of Fractionals (which are also Nums, because they are derived from it). The return type has the same type, which is evident from the type annotation (see below): a single element of Fractional

但是在fromIntegral的情况下,我无法推断自己(编译器显然可以:-)),返回的值也是Fractional的实例.为什么? 显然,它所采用的类型不是Fractional.

But in case of fromIntegral i cannot infer myself (the compiler obviously can :-)) that the returned value is also an instance of Fractional. Why? The type it takes is clearly no Fractional.

整个功能按预期工作.

仅作说明:

mySum :: (Num a) => [a] -> a myLength :: [a] -> Int

mySum :: (Num a) => [a] -> a myLength :: [a] -> Int

谢谢

拉撒路

推荐答案

fromIntegral不会产生某些未知类型,我们仅知道它是Num的实例.只要它是Num的实例,fromIntegral就会产生我们(通常是隐式)要求的任何类型.

fromIntegral doesn't produce some unknown type of which we only know that it's an instance of Num. fromIntegral produces whichever type we (usually implicitly) ask it to, as long as its an instance of Num.

就OO语言而言,您需要将其视为泛型/模板,而不是虚拟继承/子类型多态.这就是fromIntegral的等效Java签名,看起来像<A extends Integral, B extends Num> B fromIntegral(A i),而不是Num fromIntegral(Integral i).

In terms of OO languages, you need to think of it as generics/templates, not virtual inheritance/subtype polymorphism. That is the equivalent Java signature for fromIntegral would look like <A extends Integral, B extends Num> B fromIntegral(A i), not Num fromIntegral(Integral i).

所以如果我们想要一个Int,我们得到一个Int.如果我们想要一个Integer,我们将得到一个Integer.如果我们想要一个Double,我们将得到一个Double.但是,如果我们想要String,那么我们就不走运了,因为String不是Num的实例.

so if we want an Int, we get an Int. If we want an Integer, we get an Integer. And if we want a Double, we get a Double. But if we want a String, we're out of luck as String is not an instance of Num.

在这种情况下,我们需要一个a,其中a是给定列表的元素类型.因此,如果我们传递Double的列表,则fromIntegral给我们一个Double,如果我们传递Rational s的列表,则fromIntegral给我们一个Rational.

In this case we want an a where a is the element type of the given list. So if we pass in a list of Doubles, fromIntegral gives us a Double and if we pass in a list of Rationals, fromIntegral gives us a Rational.

这篇关于Haskell fromIntegral-类型混淆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆