Multiplying the value within two "Maybe" monads? - haskell

I'm currently in the process of trying to learn Haskell, and ran into an odd issue regarding the Maybe monad which I can't seem to figure out.
As an experiment, I'm currently trying to take a string, convert each letter to an arbitrary number, and multiply/combine them together. Here's what I have so far:
lookupTable :: [(Char, Int)]
lookupTable = [('A', 1), ('B', 4), ('C', -6)]
strToInts :: String -> [Maybe Int]
strToInts = map lookupChar
where
lookupChar :: Char -> Maybe Int
lookupChar c = lookup c lookupTable
-- Currently fails
test :: (Num n, Ord n) => [Maybe n] -> [Maybe n]
test seq = [ x * y | (x, y) <- zip seq $ tail seq, x < y ]
main :: IO ()
main = do
putStrLn $ show $ test $ strToInts "ABC"
When I try running this, it returns the following error:
test.hs:13:16:
Could not deduce (Num (Maybe n)) arising from a use of `*'
from the context (Num n, Ord n)
bound by the type signature for
test :: (Num n, Ord n) => [Maybe n] -> [Maybe n]
at test.hs:12:9-48
Possible fix: add an instance declaration for (Num (Maybe n))
In the expression: x * y
In the expression: [x * y | (x, y) <- zip seq $ tail seq]
In an equation for `test':
test seq = [x * y | (x, y) <- zip seq $ tail seq]
I'm not 100% sure why this error is occurring, or what it exactly means, though I suspect it might be because I'm trying to multiply two Maybe monads together -- if I change the definition of test to the following, the program compiles and runs fine:
test :: (Num n, Ord n) => [Maybe n] -> [Maybe n]
test seq = [ x | (x, y) <- zip seq $ tail seq, x < y ]
I also tried changing the type declaration to the below, but that didn't work either.
test :: (Num n, Ord n) => [Maybe n] -> [Num (Maybe n)]
I'm not really sure how to go about fixing this error. I'm fairly new to Haskell, so it might just be something really simple that I'm missing, or that I've structured everything completely wrong, but this is stumping me. What am I doing wrong?

Maybe does not have a num instance so you cannot multiply them together directly. You need to somehow apply the pure function to the values inside the context. This is exactly what applicative functors are for!
Applicative functors live in Control.Applicative:
import Control.Applicative
So you have this function and you want to apply it to 2 arguments in a context:
(*) :: Num a => a -> a -> a
You probably learned about fmap, it takes a function and applies it to a value in a context. <$> is an alias for fmap. When we fmap the pure function over the maybe value we get the following result:
(*) <$> Just 5 :: Num a => Maybe (a -> a)
So now we have maybe a function and we need to apply it to maybe a value, this is exactly what the applicative functor does. Its main operator is <*> which has the signature:
(<*>) :: f (a -> b) -> f a -> f b
When we specialize it we get the function we need:
(<*>) :: Maybe (a -> b) -> Maybe a -> Maybe b
We apply it and the output is the number you expect.
(*) <$> Just 5 <*> Just 5 :: Num a => Maybe a
So to make your code compile you need to change your test function to use <$> and <*>, see if you can figure out how.

Reite's answer is correct, and it's generally how I'd normally recommend handling it - however, it seems to me that you don't quite understand how to work with Maybe values; if so there is little sense looking at applicative functors right now.
The definition of Maybe is basically just
data Maybe a = Nothing | Just a
Which basically means exactly what it sounds like when you read it in plain english "A value of type Maybe a is either the value Nothing for that type, or a value of the form Just a".
Now you can use pattern matching to work with that, with the example of lists:
maybeReverse :: Maybe [a] -> Maybe [a]
maybeReverse Nothing = Nothing
maybeReverse (Just xs) = Just $ reverse xs
Which basically means "If the value is Nothing, then there's nothing to reverse, so the result is Nothing again. If the value is Just xs then we can reverse xs and wrap it with Just again to turn it into a Maybe [a] value).
Of course writing functions like this for every single function we ever want to use with a Maybe value would be tedious; So higher order functions to the rescue! The observation here is that in maybeReverse we didn't do all that much with reverse, we just applied it to the contained value and wrapped the result of that in Just.
So we can write a function called liftToMaybe that does this for us:
liftToMaybe :: (a->b) -> Maybe a -> Maybe b
liftToMaybe f Nothing = Nothing
liftToMaybe f (Just a) = Just $ f a
A further observation we can make is that because functions are values, we can also have Maybe values of functions. To do anything useful with those we could again unwrap them... or notice we're in the same situation as in the last paragraph, and immediately notice that we don't really care what function exactly is in that Maybe value and just write the abstraction directly:
maybeApply :: Maybe (a->b) -> Maybe a -> Maybe b
maybeApply Nothing _ = Nothing
maybeApply _ Nothing = Nothing
maybeApply (Just f) (Just a) = Just $ f a
Which, using our liftToMaybe function above, we can simplify a bit:
maybeApply :: Maybe (a->b) -> Maybe a -> Maybe b
maybeApply Nothing _ = Nothing
maybeApply (Just f) x = liftToMaybe f x
The <$> and <*> operators in Reite's answer are basically just infix names for liftToMaybe (which is also known as fmap) and maybeApply respectively; They have the types
(<$>) :: Functor f => (a->b) -> f a -> f b
(<*>) :: Applicative f => f (a->b) -> f a -> f b
You don't really need to know what the Functor and Applicative things are right now (although you should look into them at some point; They're basically generalizations of the above Maybe functions for other kinds of "context") - basically, just replace f with Maybe and you'll see that these are basically the same functions we've talked about earlier.
Now, I leave applying this to your original problem of multiplication to you (although the other answers kinda spoil it).

You are correct, the problem is that you are trying to multiply two Maybe values together, but (*) only works in instances of Num.
As it turn out, Maybe is an instance of the Applicative typeclass. This means that you can "lift" funcions that work with a type a to functions that work with a type Maybe a.
import Control.Applicative
Two functions provided by Applicative are:
pure :: a -> f a Puts a pure value in a "neutral context". For Maybe, this is Just.
(<*>) :: f (a -> b) -> f a -> f b Lets you apply a "function in a context" to two "values in a context".
So, suppose we have this pure computation:
(*) 2 3
Here are some analogous computations in a Maybe context:
Just (*) <*> Just 2 <*> Just 3
-- result is Just 6
pure (*) <*> pure 2 <*> pure 3
-- result is Just 6 -- equivalent to the above
pure (*) <*> pure 2 <*> Nothing
-- Nothing
Nothing <*> pure 2 <*> Just 3
-- Nothing
Nothing <*> Nothing <*> Nothing
-- Nothing
If the function or one of the argument is "missing", we return Nothing.
(<*>) is the explicit application operator when working with applicatives (instead of using a blank space, as when we work with pure values).
It's instructive to explore what (<*>) does with other instances of Applicative, like []:
ghci> [succ,pred] <*> pure 3
[4,2]
ghci> [succ,pred] <*> [3]
[4,2]
ghci> pure succ <*> [2,5]
[3,6]
ghci> [succ] <*> [2,5]
[3,6]
ghci> [(+),(*)] <*> pure 2 <*> pure 3
[5,6]
ghci> [(+),(*)] <*> [2,1] <*> pure 3
[5,4,6,3]
ghci> [(+),(*)] <*> [2,1] <*> [3,7]
[5,9,4,8,6,14,3,7]

Related

Can I say that Monad makes it possible to see some types as isomorphic?

Monad can pass Just [1,2], which is a different type from what the original length function takes, to >>= return . length.
Just [1,2] >>= return . length
Can I say that Monad makes it possible to see Maybe [a] as isomorphic with [a] on length using (>>=, return)? (Of course they are not really isomorphic.)
Can I choose the term "isomorphic" this situation?
What your example ultimately illustrates is that Maybe is a functor: if you have some f :: a -> b, you can use fmap to turn it into fmap f :: Maybe a -> Maybe b in a way that preserves identities and composition. Monads are functors, with \f m -> m >>= return . f being the same as fmap f m. In your case, we have the length function being transformed by the Maybe functor.
can I choose term "isomorphic" this situation?
Not really. fmap for Maybe is not an isomorphism. An isomorphism requires there being a two-sided inverse that undoes it, which in this case would be something like:
unFmapMaybe :: (Maybe a -> Maybe b) -> (a -> b)
-- For it to be a two-sided inverse to `fmap`, we should have:
unFmapMaybe . fmap = id
fmap . unFmapMaybe = id
However, there are no (Maybe a -> Maybe b) -> (a -> b) functions, as there is no way to obtain a b result if the input Maybe a -> Maybe b function gives out a Nothing. While there are specific functors whose fmap is an isomorphism (Identity is one example), that is not the case in general.
[a] is isomorphic to the quotient type of Maybe [a] with Nothing and Just [] considered equivalent. Alternatively it is isomorphic to Maybe (NonEmpty a), which simply eliminates the Just [] case.
In other words, [a] can be factorized as a composition of the Maybe and NonEmpty functors.
A result of this is that you can lift any function on NonEmpty a to a function on [a]:
liftEmptyable :: (NonEmpty a -> r) -> [a] -> Maybe r
liftEmptyable _ [] = Nothing
liftEmptyable f (x:xs) = Just $ f (x:|xs)
Not sure that actually has much to do with your question though. As duplode answered, you don't really do anything but a simple functor mapping. We could at most elaborate that the monad laws ensure that the fmap really behaves as if length acted directly on the contained list:
Just [1,2] >>= return . length
≡ return [1,2] >>= return . length -- def. of `Monad Maybe`
≡ return (length [1,2]) -- left-identity monad law

Haskell: Understanding the pure function for Applicative functors

I am learning about Applicative Functors and the pure function has the following type declaration:
pure :: a -> f a
I understand that the pure function takes a value of any type and returns an applicative value with that value inside it. So if the applicative instance was Maybe, pure 3 would give Just 3.
However, what happens when you apply pure to a value that's already inside an applicative value? E.g. what happens if you do something like pure Just 3?
What happens when you apply pure to a value that's already inside an applicative value?
It just gets wrapped in an additional layer. The end result is an applicative value nested inside another applicative value.
E.g. what happens if you do something like pure Just 3?
This is an interesting question, although probably not for the reasons you meant. The important point here is to distinguish pure (Just 3) — which was probably what you meant — from pure Just 3 = (pure Just) 3, which is what you wrote. This gives two scenarios:
pure (Just 3) simply applies pure to the value Just 3, which — as I discussed above — gives Just (Just 3), which is a nested applicative value.
(pure Just) 3 is an interesting case. Recall the types of pure and Just:
pure :: Applicative f => a -> f a
Just :: a -> Maybe a
-- so:
pure Just :: Applicative f => f (a -> Maybe a)
In other words, pure Just takes the function Just and wraps it inside an applicative value.
Next, we want to take pure Just and apply it to a value 3. But we can’t do this, since f (a -> Maybe a) is a value, not a function! So (pure Just) 3 should result in a type error.
…except it turns out to typecheck just fine! So we’re missing something. In this case, it turns out there is an applicative instance for functions:
instance Applicative ((->) r) where
pure x = \r -> x
(<*>) = _irrelevant_here
The syntax is a bit funny, but it basically means that r -> ... is an applicative. This particular instance is known as the Reader monad, and it’s very widely used. (For more about this particular data type, see e.g. here or here.) The idea is that r -> a can compute an a given an r input; in this case, pure x creates a function which ignores its input and returns x always, and f <*> x feeds the r input into both f and x, then combines the two. In this case, we’re only using pure, so it’s easy to evaluate (pure Just) 3 by hand:
(pure Just) 3
= (\r -> Just) 3
= Just
So the idea here is that pure wraps Just in an applicative value, which in this case happens to be a function; then, we apply this function to 3, which gets rid of the wrapper to reveal the original Just.
First of all, pure has the type:
pure :: Applicative f => a -> f a
To make things simpler, think of the kind of f
:k f
f :: * -> *
and the kind of a is *
then the type of a, is just a, any a, the most polymorphic of all (but with kind * remember). So you don't really care the value of a, you just have a restriction, and that's the typeclass Applicative, and the kind of f (remember * -> *)
so in this case:
gchi> pure 3 :: Maybe Int
ghci> Just 3
here f is Maybe and a is 3
In the same way
gchi> pure $ Just 3 :: Maybe (Maybe Int)
gchi> Just (Just 3)
here f is again Maybe and a is Just 3
and you can play a little changing the type to pure:
gchi> pure 3 :: [Double]
ghci> [3.0]
here, f is [], and a is 3
same way
ghci> pure [3] :: [[Double]]
ghci> [[3.0]]
finally here, f again, is [] and a is [3]

Understanding Functions as Applicatives in Haskell

I've recently been trying to learn Haskell with the "Learn You a Haskell" and have been really struggling with understanding functions as Applicatives. I should point out that using other types of Applicatives like Lists and Maybe I seem to understand well enough to use them effectively.
As I tend to do when trying to understand something is I tried to play with as many examples as I could and once the pattern emerges things tend to make sense. As such I tried a few examples. Attached are my notes of several examples I tried along with a diagram I drew to try to visualize what was happening.
The definition of funct doesnt seem to relevant to the outcome but in my tests I used a function with the following definition:
funct :: (Num a) => a -> a -> a -> a
At the bottom I tried to show the same thing as in the diagrams just using normal math notation.
So all of this is well and good, I can understand the pattern when I have some function of an arbitrary number of arguments (though needs 2 or more) and apply it to a function that takes one argument. However intuitively this pattern doesn't make that much sense to me.
So here are the specific questions I have:
What is the intuitive way to understand the pattern I'm seeing, particularly if i view an Applicative as a container (which is how I view Maybe and lists)?
What is the pattern when the function on the right of the <*> takes more than a single argument (I've mostly been using the function (+3) or (+5) on the right)?
why is the function on the right hand side of the <*> applied to the second argument of the function on the left side. For example if the function on the right hand side were f() then funct(a,b,c) turns into funct (x, f(x), c)?
Why does it work for funct <*> (+3) but not for funct <*> (+)? Moreover it DOES work for (\ a b -> 3) <*> (+)
Any explanation that gives me a better intuitive understanding for this concept would be greatly appreciated. I read other explanations such as in the book I mentioned that explains functions in terms of ((->)r) or similar patterns but even though I know how to use the ->) operator when defining a function I'm not sure i understand it in this context.
Extra Details:
I want to also include the actual code I used to help me form the diagrams above.
First I defined funct as I showed above with:
funct :: (Num a) => a -> a -> a -> a
Throughout the process i refined funct in various ways to understand what was going on.
Next I tried this code:
funct a b c = 6
functMod = funct <*> (+3)
functMod 2 3
Unsuprisingly the result was 6
So now I tried just returning each argument directly like this:
funct a b c = a
functMod = funct <*> (+3)
functMod 2 3 -- returns 2
funct a b c = b
functMod = funct <*> (+3)
functMod 2 3 -- returns 5
funct a b c = c
functMod = funct <*> (+3)
functMod 2 3 -- returns 3
From this I was able to confirm the second diagram is what was taking place. I repeated this patterns to observe the third diagram as well (which is the same patterns extended on top a second time).
You can usually understand what a function is doing in Haskell if you
substitute its definition into some examples. You already have some
examples and the definition you need is <*> for (->) a which is
this:
(f <*> g) x = f x (g x)
I don't know if you'll find any better intuition than just using the
definition a few times.
On your first example we get this:
(funct <*> (+3)) x
= funct x ((+3) x)
= funct x (x+3)
(Since there was nothing I could do with funct <*> (+3) without a
further parameter I just applied it to x - do this any time you need
to.)
And the rest:
(funct <*> (+3) <*> (+5)) x
= (funct x (x+3) <*> (+5)) x
= funct x (x+3) x ((+5) x)
= funct x (x+3) x (x+5)
(funct <*> (+)) x
= funct x ((+) x)
= funct x (x+)
Notice you can't use the same funct with both of these - in
the first it can take four numbers, but in the second it needs to take
a number and a function.
((\a b -> 3) <*> (+)) x
= (\a b -> 3) x (x+)
= (\b -> 3) (x+)
= 3
(((\a b -> a + b) <*> (+)) x
= (\a b -> a + b) x (x+)
= x + (x+)
= type error
As pointed out by David Fletcher, (<*>) for functions is:
(g <*> f) x = g x (f x)
There are two intuitive pictures of (<*>) for functions which, though not quite able to stop it from being dizzying, might help with keeping your balance as you go through code that uses it. In the next few paragraphs, I will use (+) <*> negate as a running example, so you might want to try it out a few times in GHCi before continuing.
The first picture is (<*>) as applying the result of a function to the result of another function:
g <*> f = \x -> (g x) (f x)
For instance, (+) <*> negate passes an argument to both (+) and negate, giving out a function and a number respectively, and then applies one to the other...
(+) <*> negate = \x -> (x +) (negate x)
... which explains why its result is always 0.
The second picture is (<*>) as a variation on function composition in which the argument is also used to determine what the second function to be composed will be
g <*> f = \x -> (g x . f) x
From that point of view, (+) <*> negate negates the argument and then adds the argument to the result:
(+) <*> negate = \x -> ((x +) . negate) x
If you have a funct :: Num a => a -> a -> a -> a, funct <*> (+3) works because:
In terms of the first picture: (+ 3) x is a number, and so you can apply funct x to it, ending up with funct x ((+ 3) x), a function that takes two arguments.
In terms of the second picture: funct x is a function (of type Num a => a -> a -> a) that takes a number, and so you can compose it with (+ 3) :: Num a => a -> a.
On the other hand, with funct <*> (+), we have:
In terms of the first picture: (+) x is not a number, but a Num a => a -> a function, and so you can't apply funct x to it.
In terms of the second picture: the result type of (+), when seen as a function of one argument ((+) :: Num a => a -> (a -> a)), is Num a => a -> a (and not Num a => a), and so you can't compose it with funct x (which expects a Num a => a).
For an arbitrary example of something that does work with (+) as the second argument to (<*>), consider the function iterate:
iterate :: (a -> a) -> a -> [a]
Given a function and an initial value, iterate generates an infinite list by repeatedly applying the function. If we flip the arguments to iterate, we end up with:
flip iterate :: a -> (a -> a) -> [a]
Given the problem with funct <*> (+) was that funct x wouldn't take a Num a => a -> a function, this seems to have a suitable type. And sure enough:
GHCi> take 10 $ (flip iterate <*> (+)) 1
[1,2,3,4,5,6,7,8,9,10]
(On a tangential note, you can leave out the flip if you use (=<<) instead of (<*>). That, however, is a different story.)
As a final aside, neither of the two intuitive pictures lends itself particularly well to the common use case of applicative style expressions such as:
(+) <$> (^2) <*> (^3)
To use the intuitive pictures there, you'd have to account for how (<$>) for functions is (.), which murks things quite a bit. It is easier to just see the entire thing as lifted application instead: in this example, we are adding up the results of (^2) and (^3). The equivalent spelling as...
liftA2 (+) (^2) (^3)
... somewhat emphasises that. Personally, though, I feel one possible disadvantage of writing liftA2 in this setting is that, if you apply the resulting function right in the same expression, you end up with something like...
liftA2 (+) (^2) (^3) 5
... and seeing liftA2 followed by three arguments tends to make my brain tilt.
You can view the function monad as a container. Note that it's really a separate monad for every argument-type, so we can pick a simple example: Bool.
type M a = Bool -> a
This is equivalent to
data M' a = M' { resultForFalse :: a
, resultForTrue :: a }
and the instances could be defined
instance Functor M where instance Functor M' where
fmap f (M g) = M g' fmap f (M' gFalse gTrue) = M g'False g'True
where g' False = f $ g False where g'False = f $ gFalse
g' True = f $ g True g'True = f $ gTrue
and similar for Applicative and Monad.
Of course this exhaustive case-listing definition would become totally impractical for argument-types with more than a few possible values, but it's always the same principle.
But the important thing to take away is that the instances are always specific for one particular argument. So, Bool -> Int and Bool -> String belong to the same monad, but Int -> Int and Char -> Int do not. Int -> Double -> Int does belong to the same monad as Int -> Int, but only if you consider Double -> Int as an opaque result type which has nothing to do with the Int-> monad.
So, if you're considering something like a -> a -> a -> a then this is not really a question about applicatives/monads but about Haskell in general. And therefore, you shouldn't expect that the monad=container picture gets you anywhere. To understand a -> a -> a -> a as a member of a monad, you need to pick out which of the arrows you're talking about; in this case it's only the leftmost one, i.e. you have the value M (a->a->a) in the type M=(a->) monad. The arrows between a->a->a do not participate in the monadic action in any way; if they do in your code, then it means you're actually mixing multiple monads together. Before you do that, you should understand how a single monad works, so stick to examples with only a single function arrow.

Confusion about return function and Monad

Sorry, I am a newbie to Haskell. This questions may be very easy...
From Hoogle, return signature is return :: Monad m => a -> m a
and head signature is head :: [a] -> a
Before I did this head $ return [1,2,3], I thought that ghci would throw errors because m [a] is not the same [a]. But to my surprise, it returned [1,2,3]. And tail $ return [1,2,3] returned []. Why?
One more question:
I wrote a function to generate random number:
drawFloat :: Float -> Float -> IO Float
drawFloat x y = getStdRandom (randomR (x,y))
randList = mapM (const $ drawFloat 2 10) [1..10] -- generate a list of random numbers
When I want to get the head of the list, I first tried head randList (failed) but head <$> randList worked. What is <$>? Can someone explain? Thanks!
I thought that ghci would throw errors because m [a] is not the same as [a].
Maybe not, but m [a] and [b] can unify! For example, we can set m ~ [] and b ~ [a] so that m [a] ~ [] [a] ~ [[a]] and [b] ~ [[a]]. Then we just need to check that [] is a Monad, which it is. And this is just what's happening:
> return [1,2,3] :: [[Int]]
[[1,2,3]]
Then it should be clear why head returns [1,2,3] and tail returns [].
randList = mapM (const $ drawFloat 2 10) [1..n]
As a comment, not answering your question yet: this is better spelled replicateM n (drawFloat 2 10).
head randList (failed) but head <$> randList worked. What is <$>?
The problem here is that head is still expecting a list. Before, when you were using return, the monad hadn't been chosen yet, and so it could be chosen to be []; but here, it's clear that the monad you're using is IO. So head can't make progress. The solution is to teach head how to handle IO. There are many ways, and <$> is one of them; it has this type:
> :t (<$>)
(<$>) :: Functor f => (a -> b) -> f a -> f b
The way to read this is: given a pure function, teach it how to handle IO (or any other kind of effect that qualifies as a Functor). For example, it also has this type:
(<$>) :: ([a] -> a) -> IO [a] -> IO a
There are several other kinds of teachers. Two commonly used ones are <*> and =<<:
Prelude Control.Applicative> :t (<*>)
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
Prelude Control.Applicative> :t (=<<)
(=<<) :: Monad m => (a -> m b) -> m a -> m b
Read the first as: given an effectful computation that produces a pure function, produce a function that can handle effects. The second should be read as: given a function which has some effects before it produces its output, produce a function which can handle effects.
At this point, if these explanations aren't helpful, you should turn to one of the many excellent monad tutorials available elsewhere on the web. My personal favorites are You Could Have Invented Monads! and All About Monads.
Regarding your first question:
return takes a "raw" value and gives you a monad with the value "wrapped" in it. Since you are using head and tail on return [1,2,3] , the monad in question is the list monad []. So in this context,
return [1,2,3] == [[1,2,3]]
apply head and tail on it, you will get [1,2,3] and [], respectively.
On the second question, note that the type of randList is IO [Float]. So it's not a list any more, but a list inside a monad. To apply any function to the content of the monad, you can use fmap (<$> is its infix shorthand), which has the type:
fmap :: Functor f => (a -> b) -> f a -> f b
A monad is always a Functor. So what fmap does, is that it takes an ordinary function, (head in your example), and a monadic value, applies the function to the "content" of the monad, and returns a return-value of the function wrapped in the same monad f.

Hidden features of Haskell [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
What are the lesser-known but useful features of the Haskell programming language. (I understand the language itself is lesser-known, but work with me. Even explanations of the simple things in Haskell, like defining the Fibonacci sequence with one line of code, will get upvoted by me.)
Try to limit answers to the Haskell core
One feature per answer
Give an example and short description of the feature, not just a link to documentation
Label the feature using bold title as the first line
User-defined control structures
Haskell has no shorthand ternary operator. The built-in if-then-else is always ternary, and is an expression (imperative languages tend to have ?:=expression, if=statement). If you want, though,
True ? x = const x
False ? _ = id
will define (?) to be the ternary operator:
(a ? b $ c) == (if a then b else c)
You'd have to resort to macros in most other languages to define your own short-circuiting logical operators, but Haskell is a fully lazy language, so it just works.
-- prints "I'm alive! :)"
main = True ? putStrLn "I'm alive! :)" $ error "I'm dead :("
Hoogle
Hoogle is your friend. I admit, it's not part of the "core", so cabal install hoogle
Now you know how "if you're looking for a higher-order function, it's already there" (ephemient's comment). But how do you find that function? With hoogle!
$ hoogle "Num a => [a] -> a"
Prelude product :: Num a => [a] -> a
Prelude sum :: Num a => [a] -> a
$ hoogle "[Maybe a] -> [a]"
Data.Maybe catMaybes :: [Maybe a] -> [a]
$ hoogle "Monad m => [m a] -> m [a]"
Prelude sequence :: Monad m => [m a] -> m [a]
$ hoogle "[a] -> [b] -> (a -> b -> c) -> [c]"
Prelude zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
The hoogle-google programmer is not able to write his programs on paper by himself the same way he does with the help of the computer. But he and the machine together are a forced not* to be reckoned with.
Btw, if you liked hoogle be sure to check out hlint!
My brain just exploded
If you try to compile this code:
{-# LANGUAGE ExistentialQuantification #-}
data Foo = forall a. Foo a
ignorefoo f = 1 where Foo a = f
You will get this error message:
$ ghc Foo.hs
Foo.hs:3:22:
My brain just exploded.
I can't handle pattern bindings for existentially-quantified constructors.
Instead, use a case-expression, or do-notation, to unpack the constructor.
In the binding group for
Foo a
In a pattern binding: Foo a = f
In the definition of `ignorefoo':
ignorefoo f = 1
where
Foo a = f
Free Theorems
Phil Wadler introduced us to the notion of a free theorem and we've been abusing them in Haskell ever since.
These wonderful artifacts of Hindley-Milner-style type systems help out with equational reasoning by using parametricity to tell you about what a function will not do.
For instance, there are two laws that every instance of Functor should satisfy:
forall f g. fmap f . fmap g = fmap (f . g)
fmap id = id
But, the free theorem tells us we need not bother proving the first one, but given the second it comes for 'free' just from the type signature!
fmap :: Functor f => (a -> b) -> f a -> f b
You need to be a bit careful with laziness, but this is partially covered in the original paper, and in Janis Voigtlaender's more recent paper on free theorems in the presence of seq.
Shorthand for a common list operation
The following are equivalent:
concat $ map f list
concatMap f list
list >>= f
Edit
Since more details were requested...
concat :: [[a]] -> [a]
concat takes a list of lists and concatenates them into a single list.
map :: (a -> b) -> [a] -> [b]
map maps a function over a list.
concatMap :: (a -> [b]) -> [a] -> [b]
concatMap is equivalent to (.) concat . map: map a function over a list, and concatenate the results.
class Monad m where
(>>=) :: m a -> (a -> m b) -> m b
return :: a -> m a
A Monad has a bind operation, which is called >>= in Haskell (or its sugared do-equivalent). List, aka [], is a Monad. If we substitute [] for m in the above:
instance Monad [] where
(>>=) :: [a] -> (a -> [b]) -> [b]
return :: a -> [a]
What's the natural thing for the Monad operations to do on a list? We have to satisfy the monad laws,
return a >>= f == f a
ma >>= (\a -> return a) == ma
(ma >>= f) >>= g == ma >>= (\a -> f a >>= g)
You can verify that these laws hold if we use the implementation
instance Monad [] where
(>>=) = concatMap
return = (:[])
return a >>= f == [a] >>= f == concatMap f [a] == f a
ma >>= (\a -> return a) == concatMap (\a -> [a]) ma == ma
(ma >>= f) >>= g == concatMap g (concatMap f ma) == concatMap (concatMap g . f) ma == ma >>= (\a -> f a >>= g)
This is, in fact, the behavior of Monad []. As a demonstration,
double x = [x,x]
main = do
print $ map double [1,2,3]
-- [[1,1],[2,2],[3,3]]
print . concat $ map double [1,2,3]
-- [1,1,2,2,3,3]
print $ concatMap double [1,2,3]
-- [1,1,2,2,3,3]
print $ [1,2,3] >>= double
-- [1,1,2,2,3,3]
Nestable multiline comments.
{- inside a comment,
{- inside another comment, -}
still commented! -}
Generalized algebraic data types. Here's an example interpreter where the type system lets you cover all the cases:
{-# LANGUAGE GADTs #-}
module Exp
where
data Exp a where
Num :: (Num a) => a -> Exp a
Bool :: Bool -> Exp Bool
Plus :: (Num a) => Exp a -> Exp a -> Exp a
If :: Exp Bool -> Exp a -> Exp a -> Exp a
Lt :: (Num a, Ord a) => Exp a -> Exp a -> Exp Bool
Lam :: (a -> Exp b) -> Exp (a -> b) -- higher order abstract syntax
App :: Exp (a -> b) -> Exp a -> Exp b
-- deriving (Show) -- failse
eval :: Exp a -> a
eval (Num n) = n
eval (Bool b) = b
eval (Plus e1 e2) = eval e1 + eval e2
eval (If p t f) = eval $ if eval p then t else f
eval (Lt e1 e2) = eval e1 < eval e2
eval (Lam body) = \x -> eval $ body x
eval (App f a) = eval f $ eval a
instance Eq a => Eq (Exp a) where
e1 == e2 = eval e1 == eval e2
instance Show (Exp a) where
show e = "<exp>" -- very weak show instance
instance (Num a) => Num (Exp a) where
fromInteger = Num
(+) = Plus
Patterns in top-level bindings
five :: Int
Just five = Just 5
a, b, c :: Char
[a,b,c] = "abc"
How cool is that! Saves you that call to fromJust and head every now and then.
Optional Layout
You can use explicit braces and semicolons instead of whitespace (aka layout) to delimit blocks.
let {
x = 40;
y = 2
} in
x + y
... or equivalently...
let { x = 40; y = 2 } in x + y
... instead of ...
let x = 40
y = 2
in x + y
Because layout is not required, Haskell programs can be straightforwardly produced by other programs.
seq and ($!) only evaluate enough to check that something is not bottom.
The following program will only print "there".
main = print "hi " `seq` print "there"
For those unfamiliar with Haskell, Haskell is non-strict in general, meaning that an argument to a function is only evaluated if it is needed.
For example, the following prints "ignored" and terminates with success.
main = foo (error "explode!")
where foo _ = print "ignored"
seq is known to change that behavior by evaluating to bottom if its first argument is bottom.
For example:
main = error "first" `seq` print "impossible to print"
... or equivalently, without infix ...
main = seq (error "first") (print "impossible to print")
... will blow up with an error on "first". It will never print "impossible to print".
So it might be a little surprising that even though seq is strict, it won't evaluate something the way eager languages evaluate. In particular, it won't try to force all the positive integers in the following program. Instead, it will check that [1..] isn't bottom (which can be found immediately), print "done", and exit.
main = [1..] `seq` print "done"
Operator Fixity
You can use the infix, infixl or infixr keywords to define operators associativity and precedence. Example taken from the reference:
main = print (1 +++ 2 *** 3)
infixr 6 +++
infixr 7 ***,///
(+++) :: Int -> Int -> Int
a +++ b = a + 2*b
(***) :: Int -> Int -> Int
a *** b = a - 4*b
(///) :: Int -> Int -> Int
a /// b = 2*a - 3*b
Output: -19
The number (0 to 9) after the infix allows you to define the precedence of the operator, being 9 the strongest. Infix means no associativity, whereas infixl associates left and infixr associates right.
This allows you to define complex operators to do high level operations written as simple expressions.
Note that you can also use binary functions as operators if you place them between backticks:
main = print (a `foo` b)
foo :: Int -> Int -> Int
foo a b = a + b
And as such, you can also define precedence for them:
infixr 4 `foo`
Avoiding parentheses
The (.) and ($) functions in Prelude have very convenient fixities, letting you avoid parentheses in many places. The following are equivalent:
f (g (h x))
f $ g $ h x
f . g $ h x
f . g . h $ x
flip helps too, the following are equivalent:
map (\a -> {- some long expression -}) list
flip map list $ \a ->
{- some long expression -}
Pretty guards
Prelude defines otherwise = True, making complete guard conditions read very naturally.
fac n
| n < 1 = 1
| otherwise = n * fac (n-1)
C-Style Enumerations
Combining top-level pattern matching and arithmetic sequences gives us a handy way to define consecutive values:
foo : bar : baz : _ = [100 ..] -- foo = 100, bar = 101, baz = 102
Readable function composition
Prelude defines (.) to be mathematical function composition; that is, g . f first applies f, then applies g to the result.
If you import Control.Arrow, the following are equivalent:
g . f
f >>> g
Control.Arrow provides an instance Arrow (->), and this is nice for people who don't like to read function application backwards.
let 5 = 6 in ... is valid Haskell.
Infinite Lists
Since you mentioned fibonacci, there is a very elegant way of generating fibonacci numbers from an infinite list like this:
fib#(1:tfib) = 1 : 1 : [ a+b | (a,b) <- zip fib tfib ]
The # operator allows you to use pattern matching on the 1:tfib structure while still referring to the whole pattern as fib.
Note that the comprehension list enters an infinite recursion, generating an infinite list. However, you can request elements from it or operate them, as long as you request a finite amount:
take 10 fib
You can also apply an operation to all elements before requesting them:
take 10 (map (\x -> x+1) fib)
This is thanks to Haskell's lazy evaluation of parameters and lists.
Flexible specification of module imports and exports
Importing and exporting is nice.
module Foo (module Bar, blah) -- this is module Foo, export everything that Bar expored, plus blah
import qualified Some.Long.Name as Short
import Some.Long.Name (name) -- can import multiple times, with different options
import Baz hiding (blah) -- import everything from Baz, except something named 'blah'
If you're looking for a list or higher-order function, it's already there
There's sooo many convenience and higher-order functions in the standard library.
-- factorial can be written, using the strict HOF foldl':
fac n = Data.List.foldl' (*) 1 [1..n]
-- there's a shortcut for that:
fac n = product [1..n]
-- and it can even be written pointfree:
fac = product . enumFromTo 1
Equational Reasoning
Haskell, being purely functional allows you to read an equal sign as a real equal sign (in the absence of non-overlapping patterns).
This allows you to substitute definitions directly into code, and in terms of optimization gives a lot of leeway to the compiler about when stuff happens.
A good example of this form of reasoning can be found here:
http://www.haskell.org/pipermail/haskell-cafe/2009-March/058603.html
This also manifests itself nicely in the form of laws or RULES pragmas expected for valid members of an instance, for instance the Monad laws:
returrn a >>= f == f a
m >>= return == m
(m >>= f) >>= g == m >>= (\x -> f x >>= g)
can often be used to simplify monadic code.
Laziness
Ubiquitous laziness means you can do things like define
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)
But it also provides us with a lot of more subtle benefits in terms of syntax and reasoning.
For instance, due to strictness ML has to deal with the value restriction, and is very careful to track circular let bindings, but in Haskell, we can let every let be recursive and have no need to distinguish between val and fun. This removes a major syntactic wart from the language.
This indirectly gives rise to our lovely where clause, because we can safely move computations that may or may not be used out of the main control flow and let laziness deal with sharing the results.
We can replace (almost) all of those ML style functions that need to take () and return a value, with just a lazy computation of the value. There are reasons to avoid doing so from time to time to avoid leaking space with CAFs, but such cases are rare.
Finally, it permits unrestricted eta-reduction (\x -> f x can be replaced with f). This makes combinator oriented programming for things like parser combinators much more pleasant than working with similar constructs in a strict language.
This helps you when reasoning about programs in point-free style, or about rewriting them into point-free style and reduces argument noise.
Parallel list comprehension
(Special GHC-feature)
fibs = 0 : 1 : [ a + b | a <- fibs | b <- tail fibs ]
Enhanced pattern matching
Lazy patterns
Irrefutable patterns
let ~(Just x) = someExpression
See pattern matching
Enumerations
Any type which is an instance of Enum can be used in an arithmetic sequence, not just numbers:
alphabet :: String
alphabet = ['A' .. 'Z']
Including your own datatypes, just derive from Enum to get a default implementation:
data MyEnum = A | B | C deriving(Eq, Show, Enum)
main = do
print $ [A ..] -- prints "[A,B,C]"
print $ map fromEnum [A ..] -- prints "[0,1,2]"
Monads
They are not that hidden, but they are simply everywhere, even where you don't think of them (Lists, Maybe-Types) ...

Resources