[Haskell-beginners] fromIntegral
Russ Abbott
russ.abbott at gmail.com
Fri Oct 1 11:08:08 EDT 2010
Thanks, Filipe
I clearly over-stated my case. I'd like to break it into a number of
different question. Please see below.
On Thu, Sep 30, 2010 at 10:25 PM, Felipe Lessa <felipe.lessa at gmail.com>wrote:
> I'll try to clarify some concepts. Please correct me if I am
> wrong, and please forgive me if I misunderstood you.
>
> On Fri, Oct 1, 2010 at 12:54 AM, Russ Abbott <russ.abbott at gmail.com>
> wrote:
> > In explaining fromIntegral, I want to say that it is really a collection
> of
> > overloaded functions:
> >
> > Integer -> Double
> > Int -> Float
> > ...
> >
> > When GHC compiles a line of code with fromIntegral it in, it must decide
> at
> > compile time which of these overloaded functions to compile to. This is
> in
> > contrast to saying that fromIngetral is a function of the type (Integral
> a,
> > Num b) => a -> b. In reality there is no (single) function of the type
> > (Integral a, Num b) => a -> b because (among other things) every function
> > must map between actual types, but (Integral a, Num b) => a -> b does not
> > say which actual types are mapped between.
> >
> > Is the preceding a reasonable thing to say?
>
> First of all, I do think that polymorphic functions are plain ol'
> functions. For example
>
> id :: a -> a
> id x = x
>
> is a function. Moreover, in GHC 'id' has only one
> representation, taking a thunk and returning a thunk, so even at
> the machine code level this is only one function.
>
Agree. I over stated my case. The same can be said for
length :: [a] -> Int
It doesn't matter what the type of element in the list is. length runs the
same way no matter what. So this is pure polymorphism.
>
> Now, maybe 'fromIntegral' has something more than polymorphism?
> Well, it has typeclasses. But we can represent those as
> data types, so we could write
>
> fromIntegralD :: Integral a -> Num b -> a -> b
> fromIntegralD intrDictA numDictB =
> fromIntegral numDictB . toInteger intrDictA
>
I'm afraid I don't understand this. Moreover, I couldn't get the preceding
to load without error.
>
> Better yet, the compiler could write this code for us internally.
> Now, using thunks we can get a single machine code for
> 'fromIntegralD' as well.
>
> In sum, I think all functions are really just that, functions.
>
> --
>
> You may call functions that have typeclass constraints
> "overloaded functions", but they still are functions.
>
> Functions that are polymorphic but do not have constraints are
> not really overloaded because of parametricity, which means that
> they can't change the way they work based on the specific choices
> of types you make.
>
I don't understand the preceding paragraph. Would you mind elaborating.
>
> > If so, can I say the same sort of thing about constants like 1 and []? In
> > particular there is no single value []. Instead [] is a symbol which at
> > compile time must be compiled to the empty list of some particular type,
> > e.g., [Int]. There is no such Haskell value as [] :: [a] since [a] (as
> > type) is not an actual type. I want to say the same thing about 1, i.e.,
> > that there is no such Haskell value as 1 :: (Num t) => t. When the symbol
> 1
> > appears in a program, the compiler must decide during compilation whether
> it
> > is intended to be 1::Int or 1::Integer or 1::Double, etc.
>
> Well, [a] *is* an actual type, a polymorphic one.
>
Here is the example that raised that issue for me. Let's say I define null'
as follows.
null' xs = xs == [ ]
If I don't include a declaration in the file, Haskell (reasonably) concludes
the following.
> :t null'
null' :: (Eq a) => [a] -> Bool
If I write the following at the top level, everything is fine.
> null' [ ]
True
But if I include the following in the file that defines null', I get an
error message.
test = null' [ ]
Ambiguous type variable `a' in the constraint:
`Eq a' arising from a use of `null'' at null.hs:6:17-24
Probable fix: add a type signature that fixes these type
variable(s)
Why is that? And how can it be fixed? I know I can fix it as follows.
test = null' ([ ] :: [Integer])
> :reload
> test
True
That's what suggested to me that [ ] had to be compiled into a concrete
value.
It seemed to me that similar reasoning applied to things like 1. How is the
following explained?
Prelude> 111111111111111111111111111111111111111111
111111111111111111111111111111111111111111
it :: (Num t) => t
Prelude> maxBound :: Int
2147483647
it :: Int
Prelude> 111111111111111111111111111111111111111111 - (1::Int)
-954437178
it :: Int
Does it make sense to say that the long string of 1's is really of type (Num
t) => t?
If so, what does the compiler think it's doing when it processes(?) it as an
Int so that it can subtract 1 :: Int from it? It didn't treat it as
maxBound :: Int. And yet it didn't generate an error message.
Thanks
-- Russ
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/beginners/attachments/20101001/e9fb2524/attachment-0001.html
More information about the Beginners
mailing list