Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Explicitly determining which pure function to use

One of the examples from Learn You a Haskell is:

pure (+) <*> Just 3 <*> Just 5

He states:

So at first, we have pure (+), which is Just (+)

I'm assuming that Haskell is using type inference on the <*> function to determine that the pure function on the LHS will be the one from the Maybe instance of the Applicative type class (based on the fact we're using Just 5 on the RHS, and Just is a Maybe).

However, is there ever a case where you have a value you'd like to turn into an Applicative Functor using the pure method, but you aren't going to use it right away via the <*> function and thus Haskell can't determine which pure function to use? If so, how would you be explicit state which pure function to use?

Or, is it the case that Haskell won't try to determine which pure function until the result of the pure function is used in some context (such as when you feed it to a <*> function at some point)

like image 540
ThaDon Avatar asked Jul 04 '12 16:07

ThaDon


People also ask

What is a pure function?

What Is a Pure Function? In programming, a pure function is a function that has the following properties: The function always returns the same value for the same inputs. Evaluation of the function has no side effects.

What is purepure function in C++?

Pure Function is a function (a block of code ) that always returns the same result if the same arguments are passed. It does not depend on any state, or data change during a program’s execution rather it only depends on its input arguments.

What are the side effects of using a pure function?

Evaluation of the function has no side effects. Side effects refer to changing other attributes of the program not contained within the function, such as changing global variable values or using I/O streams. Effectively, a pure function’s return value is based only on its inputs and has no other dependencies or effects on the overall program.

How can we cache the results of pure function calls?

As pure functions always return the same output for the same input, we can cache the results of pure function calls. Caching refers to using a technique, such as memoization, to store the results of functions so that we only need to calculate them once.


1 Answers

You would give it a type annotation. If you were defining it as a variable, you would use a top-level type signature:

foo :: Maybe (Integer -> Integer -> Integer)
foo = pure (+)

(This also works in let and where clauses.)

Or if you were using it in an expression, you'd write (pure (+) :: Maybe (Integer -> Integer -> Integer)).

You can also get the relevant pure function without having to apply it to an argument. Since we have:

pure :: (Applicative f) => a -> f a

...we can say (pure :: a -> Maybe a) to get a pure of the desired type. But (pure :: a -> Maybe a) (+) is more confusing than pure (+) :: Maybe (Integer -> Integer -> Integer), so the latter is probably more useful in general.

The last sentence of your question is correct, however: you can assign pure (+) to a variable without a type signature, and use it later at a specific concrete type (such as Maybe (Integer -> Integer -> Integer)) without having to use any type annotations at all. (There's a slight restriction: if you define it as a top-level variable without any type signature, then you can only use it as one specific type, not two in different places, due to the monomorphism restriction... but you probably don't need to worry about that.)

like image 56
ehird Avatar answered Oct 16 '22 06:10

ehird