<div dir="ltr"><div><div>I seem to making a mess of it, first accidentally posting an empty message and then forgetting to reply to the list. Thirdly I forgot to mention that my message only describes the 'GHCi magic'.<br>
<br></div>Lars<br><br></div>P.S. Conclusion, I shouldn't write complicated email this late on the evening.<div><div><br><div class="gmail_quote">---------- Forwarded message ----------<br>From: <b class="gmail_sendername">L Corbijn</b> <span dir="ltr"><<a href="mailto:aspergesoepje@gmail.com">aspergesoepje@gmail.com</a>></span><br>
Date: Mon, Jun 17, 2013 at 12:07 AM<br>Subject: Re: [Haskell-cafe] opengl type confusion<br>To: <a href="mailto:briand@aracnet.com">briand@aracnet.com</a><br><br><br><div dir="ltr"><div class="gmail_extra"><div><div class="h5">
<div class="gmail_quote">On Sun, Jun 16, 2013 at 11:10 PM, L Corbijn <span dir="ltr"><<a href="mailto:aspergesoepje@gmail.com" target="_blank">aspergesoepje@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div><div dir="ltr"><br></div><div class="gmail_extra"><br><br><div class="gmail_quote">
On Sun, Jun 16, 2013 at 10:42 PM, <span dir="ltr"><<a href="mailto:briand@aracnet.com" target="_blank">briand@aracnet.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>On Sun, 16 Jun 2013 16:15:25 -0400<br>
Brandon Allbery <<a href="mailto:allbery.b@gmail.com" target="_blank">allbery.b@gmail.com</a>> wrote:<br>
<br>
> On Sun, Jun 16, 2013 at 4:03 PM, <<a href="mailto:briand@aracnet.com" target="_blank">briand@aracnet.com</a>> wrote:<br>
><br>
> > Changing the declaration to GLdouble -> GLdouble -> GLdouble -> IO() and<br>
> > using<br>
> > (0.0::GLdouble) fixes it, and I'm not clear on why it's not automagic.<br>
> > There are many times I see the<br>
><br>
><br>
> Haskell never "automagic"s types in that context; if it expects GLdouble,<br>
> it expects GLdouble. Pretending it's Double will not work. It "would" in<br>
> the specific case that GLdouble were actually a type synonym for Double;<br>
> however, for performance reasons it is not. Haskell Double is not directly<br>
> usable from the C-based API used by OpenGL, so GLdouble is a type synonym<br>
> for CDouble which is.<br>
><br>
> compiler doing type conversion an numerican arguments although sometimes<br>
> > the occasional fracSomethingIntegralorOther is required.<br>
> ><br>
><br>
> I presume the reason the type specification for numeric literals is because<br>
> there is no defaulting (and probably can't be without introducing other<br>
> strange type issues) for GLdouble.<br>
><br>
<br>
</div>What I was thinking about, using a very poor choice of words, was this :<br>
<br>
<br>
*Main> let a = 1<br>
*Main> :t a<br>
a :: Integer<br>
*Main> let a = 1::Double<br>
*Main> a<br>
1.0<br>
*Main> :t a<br>
a :: Double<br>
*Main><br>
<br>
so normally 1 would be interpreted as an int, but if I declare 'a' a
Double then it gets "promoted" to a Double without me having to call a
conversion routine explicitly.<br>
<br>
That seems automagic to me.<br>
<br>
(0.0::GLdouble) works to make the compiler happy. So it appears to be taking care of the conversion automagically.<br>
<br>
So maybe a better question, I hope, is:<br>
<br>
How can I simply declare 0.0 to be (0.0::GLdouble) and have the
functional call work. Doesn't a conversion have to be happening, i.e.
shouldn't I really have to do (realToFrac 0.0) ?<br>
<div><div><br>
Brian<br>
<br>
<br>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div></div>Oops sorry for the empty reply, I accidentally hit the sent button. </div><div class="gmail_extra"><br></div><div class="gmail_extra">What you are seeing is the defaulting (see <a href="http://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-790004.3.4" target="_blank">http://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-790004.3.4</a>).
Which roughly speaking means that if you need a specific instance of a
number first try Integer then Double and as a last resort fail.<br>
<br><div class="gmail_extra">Prelude> :t 1<br>1 :: Num a => a<br></div>Prelude> :t 1.0<br>1.0 :: Fractional a => a<br><br></div><div class="gmail_extra">So normally a number can be just any instance of the Num class, and any
number with a decimal can be any Fractional instance. And now with let
bindings<br><br></div><div class="gmail_extra"><br>The need for defaulting is caused by the monomorphism restriction (<a href="http://www.haskell.org/haskellwiki/Monomorphism_restriction" target="_blank">http://www.haskell.org/haskellwiki/Monomorphism_restriction</a>),
which states that let binds should be monomorphic, or roughly speaking
it should contain no type variables (unless of course you provide a type
signature).<br>
<br>Prelude> let b = 1<br>Prelude> :t b<br>b :: Integer<br><br>Prelude> let c = 1.0<br>Prelude> :t c<br>c :: Double<br><br></div>So
here you see the result of the combination. The monomorphism
restriction doesn't allow 'Num a => a' as type for 'b'. So the
defaulting kicks in and finds that its first guess 'Integer' fits.
Therefore 'b' gets type Integer. Though for 'c' the guess 'Integer'
fails as it isn't a Fractional. Its second guess, Double, is a
fractional so 'c' gets type Double.<br>
<div><br><div class="gmail_extra">You can see that the monomorphism restriction is to blame by disabling it<br></div><div class="gmail_extra"><br>Prelude> :set -XNoMonomorphismRestriction<br>
Prelude> let b = 1<br>Prelude> :t b<br>b :: Num a => a<br><br></div><div class="gmail_extra">But you shouldn't normally need to do this, as you can provide a specific type signature.<br><br></div><div class="gmail_extra">
(in a fresh GHCi session)<br>Prelude> let {b :: Num a => a; b = 1}<br>Prelude> :t b<br>b :: Num a => a<br><br></div></div></div>
</div></div></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Sun, Jun 16, 2013 at 10:42 PM, <span dir="ltr"><<a href="mailto:briand@aracnet.com" target="_blank">briand@aracnet.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">On Sun, 16 Jun 2013 16:15:25 -0400<br>
Brandon Allbery <<a href="mailto:allbery.b@gmail.com">allbery.b@gmail.com</a>> wrote:<br>
<br>
> On Sun, Jun 16, 2013 at 4:03 PM, <<a href="mailto:briand@aracnet.com">briand@aracnet.com</a>> wrote:<br>
><br>
> > Changing the declaration to GLdouble -> GLdouble -> GLdouble -> IO() and<br>
> > using<br>
> > (0.0::GLdouble) fixes it, and I'm not clear on why it's not automagic.<br>
> > There are many times I see the<br>
><br>
><br>
> Haskell never "automagic"s types in that context; if it expects GLdouble,<br>
> it expects GLdouble. Pretending it's Double will not work. It "would" in<br>
> the specific case that GLdouble were actually a type synonym for Double;<br>
> however, for performance reasons it is not. Haskell Double is not directly<br>
> usable from the C-based API used by OpenGL, so GLdouble is a type synonym<br>
> for CDouble which is.<br>
><br>
> compiler doing type conversion an numerican arguments although sometimes<br>
> > the occasional fracSomethingIntegralorOther is required.<br>
> ><br>
><br>
> I presume the reason the type specification for numeric literals is because<br>
> there is no defaulting (and probably can't be without introducing other<br>
> strange type issues) for GLdouble.<br>
><br>
<br>
</div>What I was thinking about, using a very poor choice of words, was this :<br>
<br>
<br>
*Main> let a = 1<br>
*Main> :t a<br>
a :: Integer<br>
*Main> let a = 1::Double<br>
*Main> a<br>
1.0<br>
*Main> :t a<br>
a :: Double<br>
*Main><br>
<br>
so normally 1 would be interpreted as an int, but if I declare 'a' a Double then it gets "promoted" to a Double without me having to call a conversion routine explicitly.<br>
<br>
That seems automagic to me.<br>
<br>
(0.0::GLdouble) works to make the compiler happy. So it appears to be taking care of the conversion automagically.<br>
<br>
So maybe a better question, I hope, is:<br>
<br>
How can I simply declare 0.0 to be (0.0::GLdouble) and have the functional call work. Doesn't a conversion have to be happening, i.e. shouldn't I really have to do (realToFrac 0.0) ?<br>
<div class="HOEnZb"><div class="h5"><br>
Brian<br>
<br>
<br>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
</div></div></blockquote></div><br></div>