arithmetic on functions in haskell

A place to discuss the implementation and style of computer programs.

Moderators: phlip, Moderators General, Prelates

>-)
Posts: 512
Joined: Tue Apr 24, 2012 1:10 am UTC

arithmetic on functions in haskell

Postby >-) » Thu May 12, 2016 2:49 pm UTC

I have a function like this:

Code: Select all

foo :: Int -> Int
foo X = div ((f X) + (g X) + (h X)) ((a X) + (b X) + (c X)


where

Code: Select all

a,b,c,f,g,h :: Int -> Int

and something about the code looks a bit clunky because X is repeated so much.
Ideally I would like to have

Code: Select all

(+!) f g x = (f x) + (g x)
(/!) f g x = div (f x) (g x)


or

Code: Select all

bar op f g x = op (f x) (g x)
(+!) = bar (+)
(/!) = bar (/)


then I could write foo nicely as

Code: Select all

foo = (f +! g +! h) /! (a +! b +! c)

However, the two/three lines to define +! and /! seem like a lot of overhead.
Is something like this already built into Haskell, so I can use this idea without writing more code?

----

also as a quick side question, it seems that if i have

Code: Select all

id i = (sort [1000,999..0]) !! i

or even

Code: Select all

id i = let xs = sort [1000,999..0] in xs !! i

the list gets resorted every time I call id. Is there a way of writing this function so that the list is only sorted once?

User avatar
Flumble
Yes Man
Posts: 1944
Joined: Sun Aug 05, 2012 9:35 pm UTC

Re: arithmetic on functions in haskell

Postby Flumble » Thu May 12, 2016 8:27 pm UTC

f x + g x + h x looks a lot like you're applying x to a lots of functions and then summing the output of those functions. And the natural storage for lots of things (also functions) in Haskell is a list.
I.e. sum (map ($ x) [f,g,h]). Or in function form: sumApply x = sum . map ($ x). Or even more point-freely, (sum .) . map . flip id.

[edit] as for saving the result of (sort [1000,999..0]), are you sure Haskell's recomputing it every time? And in what context are you defining and using it?
Note that if sort produces elements at the front before elements at the back, it will postpone sorting the rest of the list until you specifically ask for an element at the end.

>-)
Posts: 512
Joined: Tue Apr 24, 2012 1:10 am UTC

Re: arithmetic on functions in haskell

Postby >-) » Thu May 12, 2016 11:03 pm UTC

thanks.

about the sorting thing. i declared in GHCi

let id i = let xs = sort [10000000,9999999..0] in xs !! i

and then computed id 1 repeatedly, and it took about the same amount of time (a few seconds) each time.

although i suppose if i actually compiled the code this would be optimized out?

User avatar
headprogrammingczar
Posts: 3072
Joined: Mon Oct 22, 2007 5:28 pm UTC
Location: Beaming you up

Re: arithmetic on functions in haskell

Postby headprogrammingczar » Fri May 13, 2016 11:45 am UTC

There's a memoization technique you can use, which removes the lambda between xs and id. Much like functions in any other language, when you define something in a lambda, it's recomputed each time that lambda is applied. What you can do is the following:

Code: Select all

-- the same as what you have now
let id = \i -> let xs = sort [10000000,9999999..0] in xs !! i

-- memoized
let id = let xs = sort [10000000,9999999..0] in \i -> xs !! i


Now it's outside the lambda and referenced by id, so as long as you keep id in memory somewhere you will also retain xs. The downside, of course, is memory consumption.

There's a library that can automate these sorts of transformations, here.
<quintopia> You're not crazy. you're the goddamn headprogrammingspock!
<Weeks> You're the goddamn headprogrammingspock!
<Cheese> I love you

User avatar
phlip
Restorer of Worlds
Posts: 7543
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: arithmetic on functions in haskell

Postby phlip » Fri May 13, 2016 1:59 pm UTC

Others have pointed out ways of doing a more fundamental rearranging of the code, but I will point out that this:
>-) wrote:

Code: Select all

bar op f g x = op (f x) (g x)
is liftA2 (or, alternatively, liftM2).

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]


Return to “Coding”

Who is online

Users browsing this forum: No registered users and 6 guests