[Haskell-beginners] why isnt this optimized?

Gunnar Quehl hasquehl at gmx.de
Fri Sep 16 10:01:12 UTC 2016


Am 16.09.2016 um 10:54 schrieb Guillaume Bouchard:
> Hello,
>
> Observe this example :
>
> Prelude> let x = f 30 in (x,x)
> (832040,832040)
> (3.70 secs, 1,649,318,104 bytes)
>
> Prelude> let x = (f 30) :: Int in (x,x)
> (832040,832040)
> (1.77 secs, 854,498,640 bytes)
>
> If we force the result type of f 30 to Int, the result is shared as expected.
>
> This is related to the monomorphism restriction
> https://wiki.haskell.org/Monomorphism_restriction
>
> We can observe the type of (x, x) :
>
> Prelude> let y = (let x = f 30 in (x, x))
> Prelude> :t y
> y :: (Num t1, Num t) => (t, t1)
>
>
> Both value does not have the same type. Actually `f` is a polymorphic
> function which can compute the result for any type t as long as t is a
> `Num`. So we can compute it for `Double`, `Float`,
> `BigMatriceOf100GigaBytesOfInfinitePrecisionRationalNumbers`. The
> compiler will only know the final type when needed, later. Actually,
> the (x, x) tuple is already computed (but `x` are unevaluated) when,
> by displaying it, you decide to fix `x` as `Integer` for both (the
> default `Num`).
>
> The setting is a bit different for compiled code, because in this
> case, the compiler choose the type earlier. For example, in a file
> `Foo.hs`
>
> a = 10
> y = (a, a) :: (Float, Integer)
>
>
> BlorkBlork.hs:2:9: error:
>      • Couldn't match expected type ‘Integer’ with actual type ‘Float’
>      • In the expression: a
>        In the expression: (a, a) :: (Float, Integer)
>        In an equation for ‘z’: z = (a, a) :: (Float, Integer)
> Failed, modules loaded: none.
>
> Because the compiler takes the first encountered type (Float) as the type of a.
>
> However you can keep the polymorphism with a type signature :
>
> a :: Num t => t
> a = 10
>
> y = (a, a) :: (Float, Integer)
>
> This is one of the rare case where adding a type signature adds
> polymorphism compared to the infered type.
>
> Will works.
>
> Hope this help.
>
Wow, this reply was much more than I expected. You are my heroe.
I actually started off with the definition

let fibs = 0:1:zipWith (+) fibs (tail fibs)

and wondered why looking at a certain cell with  for example

fibs !! 20000

always took some amount of time to evaluation, as I expected the
second time it should be already there. Now I can explain (and do
something about it, add a type signature).

Thanks that starts to become a good day



More information about the Beginners mailing list