<div dir="ltr"><div>Thank you very much</div>
<div> </div>
<div>Nadav Chernin<br><br></div>
<div class="gmail_quote">On Tue, Apr 5, 2011 at 2:56 PM, Daniel Fischer <span dir="ltr">&lt;<a href="mailto:daniel.is.fischer@googlemail.com">daniel.is.fischer@googlemail.com</a>&gt;</span> wrote:<br>
<blockquote style="BORDER-LEFT: #ccc 1px solid; MARGIN: 0px 0px 0px 0.8ex; PADDING-LEFT: 1ex" class="gmail_quote">
<div class="im">On Tuesday 05 April 2011 11:57:32, Nadav Chernin wrote:<br>&gt; How can i know when casting of types maked by compiler and when<br>&gt; programmer must to do it?<br><br></div>Generally, there are no implicit type conversions in Haskell, so you always<br>
have to do it explicitly.<br>An exception are numeric literals, an integer literal (in source code or at<br>the ghci/hugs prompt) stands for<br><br>fromInteger (integerValueParsedFromLiteral)<br>-- fromInteger :: Num n =&gt; Integer -&gt; n<br>
<br>and a floating-point literal (like 1.234e56) stands for<br><br>fromRational (rationalParsedFromLiteral)<br>-- fromRational :: Fractional a =&gt; Rational -&gt; a<br><br>Unless my memory fails, those are the only implicit conversions the<br>
language report specifies. In GHC (I don&#39;t know which other compilers, if<br>any, implement it), you can turn on the OverloadedStrings language<br>extension to get overloaded string literals (for instances of the IsString<br>
class), so &quot;this&quot; could be a String , a ByteString or a Text (and some<br>others), provided the relevant modules are in scope.<br><br>Other language extensions providing compiler-generated conversions may<br>exist (now or in future), but I&#39;m not aware of any.<br>
<br>A different, but not unrelated, issue is polymorphism (with type<br>inference).<br>When you use polymorphic expressions - like [], Nothing, (return True),<br>(realToFrac pi) - the compiler uses the context in which the expression<br>
occurs to infer the type at which the expression is used.<br>If that doesn&#39;t yield a monomorphic type, under some circumstances the type<br>gets defaulted<br>(<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>),<br>
or you get a compile error since the compiler couldn&#39;t determine what to<br>do.<br><br>If you don&#39;t use any conversion functions,<br><br>mean0 xs = sum xs / length xs,<br><br>the compiler infers<br><br>- xs :: Num n =&gt; [n]<br>
(from sum :: Num n =&gt; [n] -&gt; n)<br>- sum xs :: Fractional f =&gt; f<br>(from (/) :: Fractional f =&gt; f -&gt; f -&gt; f)<br>- combining those : xs :: (Num c, Fractional c) =&gt; [c]<br>Num is a superclass of Fractional, so the constraint can be simplified,<br>
giving<br>- xs :: Fractional c =&gt; [c]<br><br>Then (length xs :: Int), inferred from (length :: [a] -&gt; Int), as the<br>second argument of (/) forces c = Int, giving the type<br><br>mean0 :: Fractional Int =&gt; [Int] -&gt; Int<br>
<br>Normally you don&#39;t have a Fractional instance for Int in scope, so the<br>compilation would fail with a &quot;No instance ...&quot; error. If you had such an<br>instance in scope, the superfluous because fulfilled constraint would be<br>
removed, giving mean0 :: [Int] -&gt; Int.<br><br>Now, inserting the fromIntegral conversion in the second argument,<br><br>mean1 xs = sum xs / fromIntegral (length xs)<br><br>the first part remains unchanged, resulting in<br>
xs :: Fractional f =&gt; [f],<br><br>then (sum xs :: f -- for that same, as yet undetermined Fractional type f)<br>and fromIntegral&#39;s result must have the same type f.<br>Since<br><br>fromIntegral :: (Integral i, Num n) =&gt; i -&gt; n,<br>
<br>length xs :: Int, Int is an instance of Integral and Num is more general<br>than Fractional, fromIntegral (length xs) can have that type, enabling the<br>compiler to pick the right fromIntegral as soon as it knows f. Overall,<br>
<br>mean1 :: Fractional f =&gt; [f] -&gt; f,<br><br>the type f can be determined by passing a list of specific type or using<br>the result at specific type.<br><br>Inserting a conversion for the sum, say realToFrac,<br><br>
mean2 xs = realToFrac (sum xs) / fromIntegral (length xs)<br><br>changes the constraint on the type of xs&#39; elements, now it need no longer<br>be a suitable argument for (/) [Fractional], but for realToFrac [Real].<br>
(realToFrac $ sum xs) has to be the same Fractional type as<br>(fromIntegral $ length xs) but can be any Fractional type, giving<br><br>mean2 :: (Real r, Fractional f) =&gt; [r] -&gt; f<br><br>r can only be determined by passing an argument of specific type, f only by<br>
using the result at a specific type.<br>
<div>
<div></div>
<div class="h5"><br>&gt;<br>&gt; On Tue, Apr 5, 2011 at 12:14 PM, Daniel Fischer &lt;<br>&gt;<br>&gt; <a href="mailto:daniel.is.fischer@googlemail.com">daniel.is.fischer@googlemail.com</a>&gt; wrote:<br>&gt; &gt; On Tuesday 05 April 2011 10:38:37, Nadav Chernin wrote:<br>
&gt; &gt; &gt; Why only  &quot;length as&quot; we must to cast? Why &quot;sum as&quot;, that have type<br>&gt; &gt; &gt; Integer can be used in (/).<br>&gt; &gt; &gt;<br>&gt; &gt; &gt; :t (/)<br>&gt; &gt; &gt;<br>&gt; &gt; &gt; (/) :: (Fractional a) =&gt; a -&gt; a -&gt; a<br>
&gt; &gt;<br>&gt; &gt; No, sum as has the type of as&#39;s elements,<br>&gt; &gt;<br>&gt; &gt; sum :: Num a =&gt; [a] -&gt; a<br>&gt; &gt;<br>&gt; &gt; So the use of (/) refines the constraint from (Num a) to (Fractional<br>
&gt; &gt; a). if you want it to work on Integers too,<br>&gt; &gt; you&#39;d get<br>&gt; &gt;<br>&gt; &gt; mean :: (Real a, Fractional b) =&gt; [a] -&gt; b<br>&gt; &gt; mean xs = realToFrac (sum xs) / (fromIntegral $ length xs)<br>
</div></div></blockquote></div><br></div>