[Haskell-cafe] Fortran mixed mode arithmetic expressions -> Haskell

Daniel Fischer daniel.is.fischer at web.de
Sun Oct 25 23:41:28 EDT 2009


Am Montag 26 Oktober 2009 04:21:06 schrieb michael rice:
> Translating Fortran mixed mode arithmetic
> expressions into Haskell is quite a challenge.
> Believe it or not
>
> c=10.**(11-int(alog10(r)+10))
>
> translates to
>
> let c = (**) 10.0 $ fromIntegral $ subtract 11 $ truncate $ (+) (logBase
> 10.0 r) 10.0

No, subtract 11 x is x-11, not 11-x.

let c = 10^^(11 - (truncate (logBase 10 r)  + 10))

or, to make it a little simpler,

let c = 10^^(1 - truncate (logBase 10 r))

Prelude> :t (^^)
(^^) :: (Fractional a, Integral b) => a -> b -> a

That is probably faster and more accurate than (**).

>
> I finally broke the expression below into two parts
> (k1 & k2) to ease translation. I get it that Haskell is
> expecting to subtract two Integers and is instead
> being given an Integer and a Double. What must
> I do to make this work? Are there any guidelines
> for doing this kind of translation work?
>
> Michael
>
> ================
>
> Prelude> let mm = 2
> Prelude> let k1 = 3*mm+2
> Prelude> let k2 = (/) 150 119
> Prelude> let k = k1 - k2
>
> <interactive>:1:13:
>     Couldn't match expected type `Integer'
>            against inferred type `Double'
>     In the second argument of `(-)', namely `k2'
>     In the expression: k1 - k2
>     In the definition of `k': k = k1 - k2
> Prelude> :t 150/119
> 150/119 :: (Fractional t) => t
> Prelude>

In this case,

:set -XNoMonoMorphismRestriction

does the trick. In general, you have to use fromInteg[er/ral] and other conversion 
functions explicitly.

let k = fromIntegral k1 - k2



More information about the Haskell-Cafe mailing list