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

michael rice nowgate at yahoo.com
Mon Oct 26 01:00:57 EDT 2009


Hi Daniel,

I guess I only accidentally got the right answer for c=....

For my r value of 60.0

*Main> truncate $ (+) (logBase 10.0 60.0) 10.0
11
*Main> 

and subtract 11 11 == 0

Thanks for correcting me.

Also missed that 11-10=1 simplification. Forest for the trees stuff.

Your translation's definitely an improvement.

I looked for an exponential operator and grabbed the first one I
found. In the Prelude (**) is under the heading Methods, while (^^)
is under the heading Numeric Functions. Reasoning?

There's a lot of "automatic" stuff going on in Fortan mixed mode expressions, like variables that begin with I-N being integers by default, and the rest being real by default, so it's probably safer to keep things explicit in the Haskell translations.

Thanks again.

Michael

--- On Sun, 10/25/09, Daniel Fischer <daniel.is.fischer at web.de> wrote:

From: Daniel Fischer <daniel.is.fischer at web.de>
Subject: Re: [Haskell-cafe] Fortran mixed mode arithmetic expressions -> Haskell
To: haskell-cafe at haskell.org
Cc: "michael rice" <nowgate at yahoo.com>
Date: Sunday, October 25, 2009, 11:41 PM

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




      
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20091026/af0fbad4/attachment.html


More information about the Haskell-Cafe mailing list