I have a small question about value in context.
Take Just 'a', so the value in context of type Maybe in this case is 'a'
Take [3], so value in context of type [a] in this case is 3
And if you apply the monad for [3] like this: [3] >>= \x -> [x+3], it means you assign x with value 3. It's ok.
But now, take [3,2], so what is the value in the context of type [a]?. And it's so strange that if you apply monad for it like this:
[3,4] >>= \x -> x+3
It got the correct answer [6,7], but actually we don't understand what is x in this case. You can answer, ah x is 3 and then 4, and x feeds the function 2 times and concat as Monad does: concat (map f xs) like this:
[3,4] >>= concat (map f x)
So in this case, [3,4] will be assigned to the x. It means wrong, because [3,4] is not a value. Monad is wrong.
I think your problem is focusing too much on the values. A monad is a type constructor, and as such not concerned with how many and what kinds of values there are, but only the context.
A Maybe a can be an a, or nothing. Easy, and you correctly observed that.
An Either String a is either some a, or alternatively some information in form of a String (e.g. why the calculation of a failed).
Finally, [a] is an unknown number of as (or none at all), that may have resulted from an ambiguous computation, or one giving multiple results (like a quadratic equation).
Now, for the interpretation of (>>=), it is helpful to know that the essential property of a monad (how it is defined by category theorists) is
join :: m (m a) -> m a.
Together with fmap, (>>=) can be written in terms of join.
What join means is the following: A context, put in the same context again, still has the same resulting behavior (for this monad).
This is quite obvious for Maybe (Maybe a): Something can essentially be Just (Just x), or Nothing, or Just Nothing, which provides the same information as Nothing. So, instead of using Maybe (Maybe a), you could just have Maybe a and you wouldn't lose any information. That's what join does: it converts to the "easier" context.
[[a]] is somehow more difficult, but not much. You essentially have multiple/ambiguous results out of multiple/ambiguous results. A good example are the roots of a fourth-degree polynomial, found by solving a quadratic equation. You first get two solutions, and out of each you can find two others, resulting in four roots.
But the point is, it doesn't matter if you speak of an ambiguous ambiguous result, or just an ambiguous result. You could just always use the context "ambiguous", and transform multiple levels with join.
And here comes what (>>=) does for lists: it applies ambiguous functions to ambiguous values:
squareRoots :: Complex -> [Complex]
fourthRoots num = squareRoots num >>= squareRoots
can be rewritten as
fourthRoots num = join $ squareRoots `fmap` (squareRoots num)
-- [1,-1,i,-i] <- [[1,-1],[i,-i]] <- [1,-1] <- 1
since all you have to do is to find all possible results for each possible value.
This is why join is concat for lists, and in fact
m >>= f == join (fmap f) m
must hold in any monad.
A similar interpretation can be given to IO. A computation with side-effects, which can also have side-effects (IO (IO a)), is in essence just something with side-effects.
You have to take the word "context" quite broadly.
A common way of interpreting a list of values is that it represents an indeterminate value, so [3,4] represents a value which is three or four, but we don't know which (perhaps we just know it's a solution of x^2 - 7x + 12 = 0).
If we then apply f to that, we know it's 6 or 7 but we still don't know which.
Another example of an indeterminate value that you're more used to is 3. It could mean 3::Int or 3::Integer or even sometimes 3.0::Double. It feels easier because there's only one symbol representing the indeterminate value, whereas in a list, all the possibilities are listed (!).
If you write
asum = do
x <- [10,20]
y <- [1,2]
return (x+y)
You'll get a list with four possible answers: [11,12,21,22]
That's one for each of the possible ways you could add x and y.
It is not the values that are in the context, it's the types.
Just 'a' :: Maybe Char --- Char is in a Maybe context.
[3, 2] :: [Int] --- Int is in a [] context.
Whether there is one, none or many of the a in the m a is beside the point.
Edit: Consider the type of (>>=) :: Monad m => m a -> (a -> m b) -> m b.
You give the example Just 3 >>= (\x->Just(4+x)). But consider Nothing >>= (\x->Just(4+x)). There is no value in the context. But the type is in the context all the same.
It doesn't make sense to think of x as necessarily being a single value. x has a single type. If we are dealing with the Identity monad, then x will be a single value, yes. If we are in the Maybe monad, x may be a single value, or it may never be a value at all. If we are in the list monad, x may be a single value, or not be a value at all, or be various different values... but what it is not is the list of all those different values.
Your other example --- [2, 3] >>= (\x -> x + 3) --- [2, 3] is not passed to the function. [2, 3] + 3 would have a type error. 2 is passed to the function. And so is 3. The function is invoked twice, gives results for both those inputs, and the results are combined by the >>= operator. [2, 3] is not passed to the function.
"context" is one of my favorite ways to think about monads. But you've got a slight misconception.
Take Just 'a', so the value in context of type Maybe in this case is 'a'
Not quite. You keep saying the value in context, but there is not always a value "inside" a context, or if there is, then it is not necessarily the only value. It all depends on which context we are talking about.
The Maybe context is the context of "nullability", or potential absence. There might be something there, or there might be Nothing. There is no value "inside" of Nothing. So the maybe context might have a value inside, or it might not. If I give you a Maybe Foo, then you cannot assume that there is a Foo. Rather, you must assume that it is a Foo inside the context where there might actually be Nothing instead. You might say that something of type Maybe Foo is a nullable Foo.
Take [3], so value in context of type [a] in this case is 3
Again, not quite right. A list represents a nondeterministic context. We're not quite sure what "the value" is supposed to be, or if there is one at all. In the case of a singleton list, such as [3], then yes, there is just one. But one way to think about the list [3,4] is as some unobservable value which we are not quite sure what it is, but we are certain that it 3 or that it is 4. You might say that something of type [Foo] is a nondeterministic Foo.
[3,4] >>= \x -> x+3
This is a type error; not quite sure what you meant by this.
So in this case, [3,4] will be assigned to the x. It means wrong, because [3,4] is not a value. Monad is wrong.
You totally lost me here. Each instance of Monad has its own implementation of >>= which defines the context that it represents. For lists, the definition is
(xs >>= f) = (concat (map f xs))
You may want to learn about Functor and Applicative operations, which are related to the idea of Monad, and might help clear some confusion.
Related
I'm learning Haskell and making up some examples. I'm not sure why the second example doesn't work
foo :: Int -> Int -> Maybe Int
foo 0 0 = Nothing
foo a b = Just $ a + b
bar :: Int -> Maybe Int
bar 0 = Nothing
bar a = Just $ a + 1
-- This works
Just 4 >>= bar
-- Why this doesn't work?
(Just 4 Just 4) >>= foo
-- This works
do
a <- Just 3
b <- Just 4
foo a b
As the comment says, (Just 4 Just 4) tries to apply the constructor Just to 3 arguments when it only takes one. So, I will assume that you wanted something like (Just 4, Just 4), and want it to work like your final example.
The type of the "bind" operator is (>>=) :: Monad m => m a -> (m a -> b) -> m b. This means that the function expected after the operator only takes one argument, not two. So, again, the ultimate reason why it doesn't work is that, your function takes the wrong number of arguments. (Partial application means that you don't have to provide all the arguments at once, but it sounds like you're expecting some other piece of data to be magically routed to the missing argument...)
Desugaring your do example to >>= form translates as:
Just 3 >>= \a -> Just 4 >>= \b -> foo a b
To make this a little clearer, I'll parenthesize the lambdas:
Just 3 >>= ( \a -> Just 4 >>= (\b -> foo a b) )
That makes it easier to see that you can simplify the inner lambda:
Just 3 >>= ( \a -> Just 4 >>= foo a )
So, it's possible after all to route the missing data to the extra argument! But, you do have to work out the routing yourself...
There's nothing particularly magical about Haskell functions; they tend to be more particular about how they're called than dynamic languages. The largest "magic" here is that the type checker can often tell when you're not using them correctly.
And (as the other answer notes) there is nothing magical about >>= -- it's just another function, and in order to understand how to use it, you need to take a look at its type.
It doesn't work because >>= is a perfectly normal operator (and operators are perfectly normal functions).
You seem to be thinking of >>= as special syntax for getting values out of the monadic value on its left and feeding it to the function on the right. It is not special syntax; rather >>= itself is a function that gets applied to the values on its left and its right (and then computes a result as you expect).
However, that means that the left and right arguments must be valid expressions for things that could exist as ordinary values; things you could simply bind to variables with var = <expr> syntax. Just 4 >>= bar works because (among other requirements) Just 4 on its own is a valid expression of type Maybe Int and bar is a valid expression of type Int -> Maybe Int. Just 4 Just 4 >>= foo doesn't work because Just 4 Just 4 is not a correct expression (what would it's type be?); it's interpreted as applying Just to the 3 separate arguments 4, Just, and 4, whereas you want it to be two separate values Just 4 and Just 4. But even if you could get the compiler to interpret something there as two separate values, there's no way for >>= to be passed two separate values as its left argument; it's expecting (in this usage) a single value of type Just Int.
If you have a function like foo that needs two arguments and you want to source those arguments from values that are in a monadic context, then you can't just apply >>= you need to write code that does that (like your final example with the do block; there are many other ways to do something equivalent).
The other answers described why this doesn't work. But IMO it's quite reasonable that you want this, and indeed Just 3 >>= \x -> Just 4 >>= \y -> foo x y is a bit of a silly solution to the task. Basically, the x and y values are independent of each other, yet you're fetching them sequentially, in a way that the complete y calculation could in principle depend on the value of x.
Monads aren't really the right abstraction here, they're too strong. To get x and y non-sequentially, you can use Applicative interface. The form that most Haskellers prefer nowadays (I think) is
foo <$> Just 3 <*> Just 4
You can read this as “zip the effectful values Just 3 and Just 4 together to a single action with two values, then apply foo over those values”.
...Actually that's not really how it works though, and for me that was super confusing when I first learned about applicatives. Namely, the above expression is in fact parsed as
(foo <$> Just 3) <*> Just 4
which looks again like it's sequential-style. But it's not, what going on here is only a currying/laziness trick to pass multiple values through the applicative value without having to group them to a suitable tuple. The code that literally works like I explained it would be
uncurry foo <$> ((,)<$>Just 3<*>Just 4)
Here, (,)<$>Just 3<*>Just 4 evaluates to Just (3,4). Then fmapping foo over that needs to be done in uncurried form, so the two arguments are accepted as a tuple. It's structurally clear, yet awkward because we're working against Haskell's curried style.
(Mathematically, this tupling is what's conceptually happing though: generally speaking, you're working in a monoidal category. Some other incarnations of applicative functors have such a tuppling-combinator as their underlying interface, instead of <*>; e.g. >*< from the invertible package.)
The trick with foo<$>Just 3<*>Just 4 is that instead of building a tuple, we start with partially applying foo to the 3 result. This doesn't actually require anything applicative/monadic yet – we're basically just transforming the contained value – in general: values – from 3 to foo 3, without touching their context. You may consider this a purely symbolic operation. Note that the type is Maybe (Int -> Int) at this point.
Then you use the <*> combinator to zip both of the Maybe contexts together, and simultaneously apply the foo 3 partially-evaluated function to its second argument.
I personally like this form, which is also equivalent:
liftA2 foo (Just 3) (Just 4)
We're not finished yet though: all the above suggestions give a result of type Maybe (Maybe Int). To flatten that into a Maybe Int, that's where you actually need the monad interface. One option is
join $ foo <$> Just 3 <*> Just 4
I know it must sound trivial but I was wondering how you can unwrap a value from a functor and return it as pure value?
I have tried:
f::IO a->a
f x=(x>>=)
f= >>=
What should I place in the right side? I can't use return since it will wrap it back again.
It's a frequently asked question: How do I extract 'the' value from my monad, not only in Haskell, but in other languages as well. I have a theory about why this question keeps popping up, so I'll try to answer according to that; I hope it helps.
Containers of single values
You can think of a functor (and therefore also a monad) as a container of values. This is most palpable with the (redundant) Identity functor:
Prelude Control.Monad.Identity> Identity 42
Identity 42
This is nothing but a wrapper around a value, in this case 42. For this particular container, you can extract the value, because it's guaranteed to be there:
Prelude Control.Monad.Identity> runIdentity $ Identity 42
42
While Identity seems fairly useless, you can find other functors that seem to wrap a single value. In F#, for example, you'll often encounter containers like Async<'a> or Lazy<'a>, which are used to represent asynchronous or lazy computations (Haskell doesn't need the latter, because it's lazy by default).
You'll find lots of other single-value containers in Haskell, such as Sum, Product, Last, First, Max, Min, etc. Common to all of those is that they wrap a single value, which means that you can extract the value.
I think that when people first encounter functors and monads, they tend to think of the concept of a data container in this way: as a container of a single value.
Containers of optional values
Unfortunately, some common monads in Haskell seem to support that idea. For example, Maybe is a data container as well, but one that can contain zero or one value. You can, unfortunately, still extract the value if it's there:
Prelude Data.Maybe> fromJust $ Just 42
42
The problem with this is that fromJust isn't total, so it'll crash if you call it with a Nothing value:
Prelude Data.Maybe> fromJust Nothing
*** Exception: Maybe.fromJust: Nothing
You can see the same sort of problem with Either. Although I'm not aware of a built-in partial function to extract a Right value, you can easily write one with pattern matching (if you ignore the compiler warning):
extractRight :: Either l r -> r
extractRight (Right x) = x
Again, it works in the 'happy path' scenario, but can just as easily crash:
Prelude> extractRight $ Right 42
42
Prelude> extractRight $ Left "foo"
*** Exception: <interactive>:12:1-26: Non-exhaustive patterns in function extractRight
Still, since functions like fromJust exists, I suppose it tricks people new to the concept of functors and monads into thinking about them as data containers from which you can extract a value.
When you encounter something like IO Int for the first time, then, I can understand why you'd be tempted to think of it as a container of a single value. In a sense, it is, but in another sense, it isn't.
Containers of multiple values
Even with lists, you can (attempt to) extract 'the' value from a list:
Prelude> head [42..1337]
42
Still, it could fail:
Prelude> head []
*** Exception: Prelude.head: empty list
At this point, however, it should be clear that attempting to extract 'the' value from any arbitrary functor is nonsense. A list is a functor, but it contains an arbitrary number of values, including zero and infinitely many.
What you can always do, though, is to write functions that take a 'contained' value as input and returns another value as output. Here's an arbitrary example of such a function:
countAndMultiply :: Foldable t => (t a, Int) -> Int
countAndMultiply (xs, factor) = length xs * factor
While you can't 'extract the value' out of a list, you can apply your function to each of the values in a list:
Prelude> fmap countAndMultiply [("foo", 2), ("bar", 3), ("corge", 2)]
[6,9,10]
Since IO is a functor, you can do the same with it as well:
Prelude> foo = return ("foo", 2) :: IO (String, Int)
Prelude> :t foo
foo :: IO (String, Int)
Prelude> fmap countAndMultiply foo
6
The point is that you don't extract a value from a functor, you step into the functor.
Monad
Sometimes, the function you apply to a functor returns a value that's already wrapped in the same data container. As an example, you may have a function that splits a string over a particular character. To keep things simple, let's just look at the built-in function words that splits a string into words:
Prelude> words "foo bar"
["foo","bar"]
If you have a list of strings, and apply words to each, you'll get a nested list:
Prelude> fmap words ["foo bar", "baz qux"]
[["foo","bar"],["baz","qux"]]
The result is a nested data container, in this case a list of lists. You can flatten it with join:
Prelude Control.Monad> join $ fmap words ["foo bar", "baz qux"]
["foo","bar","baz","qux"]
This is the original definition of a monad: it's a functor that you can flatten. In modern Haskell, Monad is defined by bind (>>=), from which one can derive join, but it's also possible to derive >>= from join.
IO as all values
At this point, you may be wondering: what does that have to do with IO? Isn't IO a a container of a single value of the type a?
Not really. One interpretation of IO is that it's a container that holds an arbitrary value of the type a. According to that interpretation, it's analogous to the many-worlds interpretation of quantum mechanics. IO a is the superposition of all possible values of the type a.
In Schrödinger's original thought experiment, the cat in the box is both alive and dead until observed. That's two possible states superimposed. If we think about a variable called catIsAlive, it would be equivalent to the superposition of True and False. So, you can think of IO Bool as a set of possible values {True, False} that will only collapse into a single value when observed.
Likewise, IO Word8 can be interpreted as a superposition of the set of all possible Word8 values, i.e. {0, 1, 2,.. 255}, IO Int as the superposition of all possible Int values, IO String as all possible String values (i.e. an infinite set), and so on.
So how do you observe the value, then?
You don't extract it, you work within the data container. You can, as shown above, fmap and join over it. So, you can write your application as pure functions that you then compose with impure values with fmap, >>=, join, and so on.
It is trivial, so this will be a long answer. In short, the problem lies in the signature, IO a -> a, is not a type properly allowed in Haskell. This really has less to do with IO being a functor than the fact that IO is special.
For some functors you can recover the pure value. For instance a partially applied pair, (,) a, is a functor. We unwrap the value via snd.
snd :: (a,b) -> b
snd (_,b) = b
So this is a functor that we can unwrap to a pure value, but this really has nothing to do with being a functor. It has more to do with pairs belonging to a different Category Theoretic concept, Comonad, with:
extract :: Comonad w => w a -> a
Any Comonad will be a functor for which you can recover the pure value.
Many (non-comonadic) functors have--lets say "evaluators"--which allow something like what is being asked. For instance, we can evaluate a Maybe with maybe :: a -> Maybe a -> a. By providing a default, maybe a has the desired type, Maybe a -> a. Another useful example from State, evalState :: State s a -> s -> a, has its arguments reversed but the concept is the same; given the monad, State s a, and initial state, s, we unwrap the pure value, a.
Finally to the specifics of IO. No "evaluator" for IO is provided in the Haskell language or libraries. We might consider running the program itself an evaluator--much in the same vein of evalState. But if that's a valid conceptual move, then it should only help to convince you that there is no sane way to unwrap from IO--any program written is just the IO a input to its evaluator function.
Instead, what you are forced to do--by design--is to work within the IO monad. For instance, if you have a pure function, f :: a -> b, you apply it within the IO context via, fmap f :: IO a -> IO b
TL;DR You can't get a pure value out of the IO monad. Apply pure functions within the IO context, for instance by fmap
Going through Haskell's documentation is always a bit of a pain for me, because all the information you get about a function is often nothing more than just: f a -> f [a] which could mean any number of things.
As is the case of the <|> function.
All I'm given is this: (<|>) :: f a -> f a -> f a and that it's an "associative binary operation"...
Upon inspection of Control.Applicative I learn that it does seemingly unrelated things depending on implementation.
instance Alternative Maybe where
empty = Nothing
Nothing <|> r = r
l <|> _ = l
Ok, so it returns right if there is no left, otherwise it returns left, gotcha.. This leads me to believe it's a "left or right" operator, which kinda makes sense given its use of | and |'s historical use as "OR"
instance Alternative [] where
empty = []
(<|>) = (++)
Except here it just calls list's concatenation operator... Breaking my idea down...
So what exactly is that function? What's its use? Where does it fit in in the grand scheme of things?
Typically it means "choice" or "parallel" in that a <|> b is either a "choice" of a or b or a and b done in parallel. But let's back up.
Really, there is no practical meaning to operations in typeclasses like (<*>) or (<|>). These operations are given meaning in two ways: (1) via laws and (2) via instantiations. If we are not talking about a particular instance of Alternative then only (1) is available for intuiting meaning.
So "associative" means that a <|> (b <|> c) is the same as (a <|> b) <|> c. This is useful as it means that we only care about the sequence of things chained together with (<|>), not their "tree structure".
Other laws include identity with empty. In particular, a <|> empty = empty <|> a = a. In our intuition with "choice" or "parallel" these laws read as "a or (something impossible) must be a" or "a alongside (empty process) is just a". It indicates that empty is some kind of "failure mode" for an Alternative.
There are other laws with how (<|>)/empty interact with fmap (from Functor) or pure/(<*>) (from Applicative), but perhaps the best way to move forward in understanding the meaning of (<|>) is to examine a very common example of a type which instantiates Alternative: a Parser.
If x :: Parser A and y :: Parser B then (,) <$> x <*> y :: Parser (A, B) parses x and then y in sequence. In contrast, (fmap Left x) <|> (fmap Right y) parses either x or y, beginning with x, to try out both possible parses. In other words, it indicates a branch in your parse tree, a choice, or a parallel parsing universe.
(<|>) :: f a -> f a -> f a actually tells you quite a lot, even without considering the laws for Alternative.
It takes two f a values, and has to give one back. So it will have to combine or select from its inputs somehow. It's polymorphic in the type a, so it will be completely unable to inspect whatever values of type a might be inside an f a; this means it can't do the "combining" by combining a values, so it must to it purely in terms of whatever structure the type constructor f adds.
The name helps a bit too. Some sort of "OR" is indeed the vague concept the authors were trying to indicate with the name "Alternative" and the symbol "<|>".
Now if I've got two Maybe a values and I have to combine them, what can I do? If they're both Nothing I'll have to return Nothing, with no way to create an a. If at least one of them is a Just ... I can return one of my inputs as-is, or I can return Nothing. There are very few functions that are even possible with the type Maybe a -> Maybe a -> Maybe a, and for a class whose name is "Alternative" the one given is pretty reasonable and obvious.
How about combining two [a] values? There are more possible functions here, but really it's pretty obvious what this is likely to do. And the name "Alternative" does give you a good hint at what this is likely to be about provided you're familiar with the standard "nondeterminism" interpretation of the list monad/applicative; if you see a [a] as a "nondeterministic a" with a collection of possible values, then the obvious way for "combining two nondeterministic a values" in a way that might deserve the name "Alternative" is to produce a nondeterminstic a which could be any of the values from either of the inputs.
And for parsers; combining two parsers has two obvious broad interpretations that spring to mind; either you produce a parser that would match what the first does and then what the second does, or you produce a parser that matches either what the first does or what the second does (there are of course subtle details of each of these options that leave room for options). Given the name "Alternative", the "or" interpretation seems very natural for <|>.
So, seen from a sufficiently high level of abstraction, these operations do all "do the same thing". The type class is really for operating at that high level of abstraction where these things all "look the same". When I'm operating on a single known instance I just think of the <|> operation as exactly what it does for that specific type.
An interesting example of an Alternative that isn't a parser or a MonadPlus-like thing is Concurrently, a very useful type from the async package.
For Concurrently, empty is a computation that goes on forever. And (<|>) executes its arguments concurrently, returns the result of the first one that completes, and cancels the other one.
These seem very different, but consider:
Nothing <|> Nothing == Nothing
[] <|> [] == []
Just a <|> Nothing == Just a
[a] <|> [] == [a]
Nothing <|> Just b == Just b
[] <|> [b] == [b]
So... these are actually very, very similar, even if the implementation looks different. The only real difference is here:
Just a <|> Just b == Just a
[a] <|> [b] == [a, b]
A Maybe can only hold one value (or zero, but not any other amount). But hey, if they were both identical, why would you need two different types? The whole point of them being different is, you know, to be different.
In summary, the implementation may look totally different, but these are actually quite similar.
I don't think I quite understand currying, since I'm unable to see any massive benefit it could provide. Perhaps someone could enlighten me with an example demonstrating why it is so useful. Does it truly have benefits and applications, or is it just an over-appreciated concept?
(There is a slight difference between currying and partial application, although they're closely related; since they're often mixed together, I'll deal with both terms.)
The place where I realized the benefits first was when I saw sliced operators:
incElems = map (+1)
--non-curried equivalent: incElems = (\elems -> map (\i -> (+) 1 i) elems)
IMO, this is totally easy to read. Now, if the type of (+) was (Int,Int) -> Int *, which is the uncurried version, it would (counter-intuitively) result in an error -- but curryied, it works as expected, and has type [Int] -> [Int].
You mentioned C# lambdas in a comment. In C#, you could have written incElems like so, given a function plus:
var incElems = xs => xs.Select(x => plus(1,x))
If you're used to point-free style, you'll see that the x here is redundant. Logically, that code could be reduced to
var incElems = xs => xs.Select(curry(plus)(1))
which is awful due to the lack of automatic partial application with C# lambdas. And that's the crucial point to decide where currying is actually useful: mostly when it happens implicitly. For me, map (+1) is the easiest to read, then comes .Select(x => plus(1,x)), and the version with curry should probably be avoided, if there is no really good reason.
Now, if readable, the benefits sum up to shorter, more readable and less cluttered code -- unless there is some abuse of point-free style done is with it (I do love (.).(.), but it is... special)
Also, lambda calculus would get impossible without using curried functions, since it has only one-valued (but therefor higher-order) functions.
* Of course it actually in Num, but it's more readable like this for the moment.
Update: how currying actually works.
Look at the type of plus in C#:
int plus(int a, int b) {..}
You have to give it a tuple of values -- not in C# terms, but mathematically spoken; you can't just leave out the second value. In haskell terms, that's
plus :: (Int,Int) -> Int,
which could be used like
incElem = map (\x -> plus (1, x)) -- equal to .Select (x => plus (1, x))
That's way too much characters to type. Suppose you'd want to do this more often in the future. Here's a little helper:
curry f = \x -> (\y -> f (x,y))
plus' = curry plus
which gives
incElem = map (plus' 1)
Let's apply this to a concrete value.
incElem [1]
= (map (plus' 1)) [1]
= [plus' 1 1]
= [(curry plus) 1 1]
= [(\x -> (\y -> plus (x,y))) 1 1]
= [plus (1,1)]
= [2]
Here you can see curry at work. It turns a standard haskell style function application (plus' 1 1) into a call to a "tupled" function -- or, viewed at a higher level, transforms the "tupled" into the "untupled" version.
Fortunately, most of the time, you don't have to worry about this, as there is automatic partial application.
It's not the best thing since sliced bread, but if you're using lambdas anyway, it's easier to use higher-order functions without using lambda syntax. Compare:
map (max 4) [0,6,9,3] --[4,6,9,4]
map (\i -> max 4 i) [0,6,9,3] --[4,6,9,4]
These kinds of constructs come up often enough when you're using functional programming, that it's a nice shortcut to have and lets you think about the problem from a slightly higher level--you're mapping against the "max 4" function, not some random function that happens to be defined as (\i -> max 4 i). It lets you start to think in higher levels of indirection more easily:
let numOr4 = map $ max 4
let numOr4' = (\xs -> map (\i -> max 4 i) xs)
numOr4 [0,6,9,3] --ends up being [4,6,9,4] either way;
--which do you think is easier to understand?
That said, it's not a panacea; sometimes your function's parameters will be the wrong order for what you're trying to do with currying, so you'll have to resort to a lambda anyway. However, once you get used to this style, you start to learn how to design your functions to work well with it, and once those neurons starts to connect inside your brain, previously complicated constructs can start to seem obvious in comparison.
One benefit of currying is that it allows partial application of functions without the need of any special syntax/operator. A simple example:
mapLength = map length
mapLength ["ab", "cde", "f"]
>>> [2, 3, 1]
mapLength ["x", "yz", "www"]
>>> [1, 2, 3]
map :: (a -> b) -> [a] -> [b]
length :: [a] -> Int
mapLength :: [[a]] -> [Int]
The map function can be considered to have type (a -> b) -> ([a] -> [b]) because of currying, so when length is applied as its first argument, it yields the function mapLength of type [[a]] -> [Int].
Currying has the convenience features mentioned in other answers, but it also often serves to simplify reasoning about the language or to implement some code much easier than it could be otherwise. For example, currying means that any function at all has a type that's compatible with a ->b. If you write some code whose type involves a -> b, that code can be made work with any function at all, no matter how many arguments it takes.
The best known example of this is the Applicative class:
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
And an example use:
-- All possible products of numbers taken from [1..5] and [1..10]
example = pure (*) <*> [1..5] <*> [1..10]
In this context, pure and <*> adapt any function of type a -> b to work with lists of type [a]. Because of partial application, this means you can also adapt functions of type a -> b -> c to work with [a] and [b], or a -> b -> c -> d with [a], [b] and [c], and so on.
The reason this works is because a -> b -> c is the same thing as a -> (b -> c):
(+) :: Num a => a -> a -> a
pure (+) :: (Applicative f, Num a) => f (a -> a -> a)
[1..5], [1..10] :: Num a => [a]
pure (+) <*> [1..5] :: Num a => [a -> a]
pure (+) <*> [1..5] <*> [1..10] :: Num a => [a]
Another, different use of currying is that Haskell allows you to partially apply type constructors. E.g., if you have this type:
data Foo a b = Foo a b
...it actually makes sense to write Foo a in many contexts, for example:
instance Functor (Foo a) where
fmap f (Foo a b) = Foo a (f b)
I.e., Foo is a two-parameter type constructor with kind * -> * -> *; Foo a, the partial application of Foo to just one type, is a type constructor with kind * -> *. Functor is a type class that can only be instantiated for type constrcutors of kind * -> *. Since Foo a is of this kind, you can make a Functor instance for it.
The "no-currying" form of partial application works like this:
We have a function f : (A ✕ B) → C
We'd like to apply it partially to some a : A
To do this, we build a closure out of a and f (we don't evaluate f at all, for the time being)
Then some time later, we receive the second argument b : B
Now that we have both the A and B argument, we can evaluate f in its original form...
So we recall a from the closure, and evaluate f(a,b).
A bit complicated, isn't it?
When f is curried in the first place, it's rather simpler:
We have a function f : A → B → C
We'd like to apply it partially to some a : A – which we can just do: f a
Then some time later, we receive the second argument b : B
We apply the already evaluated f a to b.
So far so nice, but more important than being simple, this also gives us extra possibilities for implementing our function: we may be able to do some calculations as soon as the a argument is received, and these calculations won't need to be done later, even if the function is evaluated with multiple different b arguments!
To give an example, consider this audio filter, an infinite impulse response filter. It works like this: for each audio sample, you feed an "accumulator function" (f) with some state parameter (in this case, a simple number, 0 at the beginning) and the audio sample. The function then does some magic, and spits out the new internal state1 and the output sample.
Now here's the crucial bit – what kind of magic the function does depends on the coefficient2 λ, which is not quite a constant: it depends both on what cutoff frequency we'd like the filter to have (this governs "how the filter will sound") and on what sample rate we're processing in. Unfortunately, the calculation of λ is a bit more complicated (lp1stCoeff $ 2*pi * (νᵥ ~*% δs) than the rest of the magic, so we wouldn't like having to do this for every single sample, all over again. Quite annoying, because νᵥ and δs are almost constant: they change very seldom, certainly not at each audio sample.
But currying saves the day! We simply calculate λ as soon as we have the necessary parameters. Then, at each of the many many audio samples to come, we only need to perform the remaining, very easy magic: yⱼ = yⱼ₁ + λ ⋅ (xⱼ - yⱼ₁). So we're being efficient, and still keeping a nice safe referentially transparent purely-functional interface.
1 Note that this kind of state-passing can generally be done more nicely with the State or ST monad, that's just not particularly beneficial in this example
2 Yes, this is a lambda symbol. I hope I'm not confusing anybody – fortunately, in Haskell it's clear that lambda functions are written with \, not with λ.
It's somewhat dubious to ask what the benefits of currying are without specifying the context in which you're asking the question:
In some cases, like functional languages, currying will merely be seen as something that has a more local change, where you could replace things with explicit tupled domains. However, this isn't to say that currying is useless in these languages. In some sense, programming with curried functions make you "feel" like you're programming in a more functional style, because you more typically face situations where you're dealing with higher order functions. Certainly, most of the time, you will "fill in" all of the arguments to a function, but in the cases where you want to use the function in its partially applied form, this is a bit simpler to do in curried form. We typically tell our beginning programmers to use this when learning a functional language just because it feels like better style and reminds them they're programming in more than just C. Having things like curry and uncurry also help for certain conveniences within functional programming languages too, I can think of arrows within Haskell as a specific example of where you would use curry and uncurry a bit to apply things to different pieces of an arrow, etc...
In some cases, you want to think about more than functional programs, you can present currying / uncurrying as a way to state the elimination and introduction rules for and in constructive logic, which provides a connection to a more elegant motivation for why it exists.
In some cases, for example, in Coq, using curried functions versus tupled functions can produce different induction schemes, which may be easier or harder to work with, depending on your applications.
I used to think that currying was simple syntax sugar that saves you a bit of typing. For example, instead of writing
(\ x -> x + 1)
I can merely write
(+1)
The latter is instantly more readable, and less typing to boot.
So if it's just a convenient short cut, why all the fuss?
Well, it turns out that because function types are curried, you can write code which is polymorphic in the number of arguments a function has.
For example, the QuickCheck framework lets you test functions by feeding them randomly-generated test data. It works on any function who's input type can be auto-generated. But, because of currying, the authors were able to rig it so this works with any number of arguments. Were functions not curried, there would be a different testing function for each number of arguments - and that would just be tedious.
I am a beginner with haskell and am reading the Learn you a haskell book. I have been trying to digest functors and applicative functors for a while now.
In the applicative functors topic, the instance implementation for Maybe is given as
instance Applicative Maybe where
pure = Just
Nothing <*> _ = Nothing
(Just f) <*> something = fmap f something
So, as I understand it, we get Nothing if the left side functor (for <*>) is Nothing. To me, it seems to make more sense as
Nothing <*> something = something
So that this applicative functor has no effect. What is the usecase, if any for giving out Nothing?
Say, I have a Maybe String with me, whose value I don't know. I have to give this Maybe to a third party function, but want its result to go through a few Maybe (a -> b)'s first. If some of these functions are Nothing I'll want them to silently return their input, not give out a Nothing, which is loss of data.
So, what is the thinking behind returning Nothing in the above instance?
How would that work? Here's the type signature:
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
So the second argument here would be of type Maybe a, while the result needs to be of type Maybe b. You need some way to turn a into b, which you can only do if the first argument isn't Nothing.
The only way something like this would work is if you have one or more values of type Maybe (a -> a) and want to apply any that aren't Nothing. But that's much too specific for the general definition of (<*>).
Edit: Since it seems to be the Maybe (a -> a) scenario you actually care about, here's a couple examples of what you can do with a bunch of values of that type:
Keeping all the functions and discard the Nothings, then apply them:
applyJust :: [Maybe (a -> a)] -> a -> a
applyJust = foldr (.) id . catMaybes
The catMaybes function gives you a list containing only the Just values, then the foldr composes them all together, starting from the identity function (which is what you'll get if there are no functions to apply).
Alternatively, you can take functions until finding a Nothing, then bail out:
applyWhileJust :: [Maybe (a -> a)] -> a -> a
applyWhileJust (Just f:fs) = f . applyWhileJust fs
applyWhileJust (Nothing:_) = id
This uses a similar idea as the above, except that when it finds Nothing it ignores the rest of the list. If you like, you can also write it as applyWhileJust = foldr (maybe (const id) (.)) id but that's a little harder to read...
Think of the <*> as the normal * operator. a * 0 == 0, right? It doesn't matter what a is. So using the same logic, Just (const a) <*> Nothing == Nothing. The Applicative laws dictate that a data type has to behave like this.
The reason why this is useful, is that Maybe is supposed to represent the presence of something, not the absence of something. If you pipeline a Maybe value through a chain of functions, if one function fails, it means that a failure happened, and that the process needs to be aborted.
The behavior you propose is impractical, because there are numerous problems with it:
If a failed function is to return its input, it has to have type a -> a, because the returned value and the input value have to have the same type for them to be interchangeable depending on the outcome of the function
According to your logic, what happens if you have Just (const 2) <*> Just 5? How can the behavior in this case be made consistent with the Nothing case?
See also the Applicative laws.
EDIT: fixed code typos, and again
Well what about this?
Just id <*> Just something
The usecase for Nothing comes when you start using <*> to plumb through functions with multiple inputs.
(-) <$> readInt "foo" <*> readInt "3"
Assuming you have a function readInt :: String -> Maybe Int, this will turn into:
(-) <$> Nothing <*> Just 3
<$> is just fmap, and fmap f Nothing is Nothing, so it reduces to:
Nothing <*> Just 3
Can you see now why this should produce Nothing? The original meaning of the expression was to subtract two numbers, but since we failed to produce a partially-applied function after the first input, we need to propagate that failure instead of just making up a nice function that has nothing to do with subtraction.
Additional to C. A. McCann's excellent answer I'd like to point out that this might be a case of a "theorem for free", see http://ttic.uchicago.edu/~dreyer/course/papers/wadler.pdf . The gist of this paper is that for some polymorphic functions there is only one possible implementiation for a given type signature, e.g. fst :: (a,b) -> a has no other choice than returning the first element of the pair (or be undefined), and this can be proven. This property may seem counter-intuitive but is rooted in the very limited information a function has about its polymorphic arguments (especially it can't create one out of thin air).