Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

`seq` on partially applied functions

Tags:

haskell

seq

Lets say I have the following:

f :: a -> b -> c
g :: b -> c
g = f 10

Now lets say f is actually:

f x y = f1 x + y

Would:

g `seq` ...

actually evaluate f1 10, so later when running

g 9

it's actually just a simple addition?

If not, is there a way to "evaluate" parts of a partially applied function?

I'm looking for a generic solution, one that doesn't depend on knowing how f and g work.

like image 458
Clinton Avatar asked Apr 16 '12 07:04

Clinton


People also ask

What is partially applied function?

The Partially applied functions are the functions which are not applied on all the arguments defined by the stated function i.e, while invoking a function, we can supply some of the arguments and the left arguments are supplied when required.

Can a partial function be Injective?

Many properties of functions can be extended in an appropriate sense of partial functions. A partial function is said to be injective, surjective, or bijective when the function given by the restriction of the partial function to its domain of definition is injective, surjective, bijective respectively.

What is the difference between a partial function and partial application?

Partial application results in a function of smaller arity; in the example above, f has an arity of 3 while partial only has an arity of 2. More importantly, a partially applied function would return the result right away upon being invoke, not another function down the currying chain.

What is the difference between currying and partial application?

Currying: A function returning another function that might return another function, but every returned function must take only one parameter at a time. Partial application: A function returning another function that might return another function, but each returned function can take several parameters.


2 Answers

No, it will not, because in general, the choice of right hand side for f might depend on y. If you want to share the result of f1 x between calls to g, you would have to write f like this:

f x = let z = f1 x in \y -> z + y

Of course, due to laziness this will not evaluate f1 x until the first time g is called. To have g `seq` ... force evaluation of f1 x, you would have to write:

f x = let z = f1 x in z `seq` (\y -> z + y)
like image 153
hammar Avatar answered Oct 01 '22 03:10

hammar


seq is shallow:

Prelude> let f1 = undefined
Prelude> let f = \x -> \y -> f1 x + y
Prelude> let g = f 10
Prelude> g `seq` 1
1
Prelude> g 9
*** Exception: Prelude.undefined
Prelude>

I'd take a look at Control.DeepSeq: http://hackage.haskell.org/packages/archive/deepseq/1.2.0.1/doc/html/Control-DeepSeq.html

like image 21
Deestan Avatar answered Oct 01 '22 04:10

Deestan