Haskell Pattern matching in let on function return vs function arguments - haskell

As a beginner at Haskell I've found it difficult to visually recognize some examples of pattern matching.
It seems that in let bindings sometimes the pattern matching occurs on the lhs when a function is called and the values are bound to variables in the equation on the rhs like in the following code example:
let boot x y z = x * y + z in boot 3 4 2
Sometimes however a function will be run in the rhs and the return values of that function will be bound to values in the lhs of the equation as in the definition of the State Monad from "Learn you a Haskell":
instance Monad (State s) where
return x = State $ \s -> (x,s)
(State h) >>= f = State $ \s -> let (a, newState) = h s
(State g) = f a
in g newState
where the function h is run with the lambda argument s and the return values are bound to (a, newState).
To a new Haskell programmer, this is slightly confusing. I could imagine a scenario where you might have:
let f a b = g c d in ...
where the function g would return a function and two arguments as it's return values. In this case would the "f a b" need to be wrapped in parenthesis for the pattern match to occur? I'm trying to find a definitive explanation of how the pattern matching occurs.
I have read most of "Learn You A Haskell For Great Good", as well as snippets from "Real World Haskell" and "A Gentle Introduction to Haskell" and I have not found a clear explanation of how to determine if the pattern matching should be occuring on arguments to a function or on the return values of a function. Any help in clearing this up would be appreciated.

I believe you're stumbling over the difference between function and pattern bindings.
In short, if you have something like "variable pat1 pat2 ... =" (where pat1 pat2 ... are one or more patterns), it's a function binding; otherwise it's a pattern binding. In the most simple case, x y z = ..., a function binding is just syntactic sugar for a lambda: x = \y z -> ....
If it starts with a (, it's not a variable, so the whole thing must be a pattern binding. But even without parens State x is still a pattern binding because State is not a variable (it starts with an uppercase letter so it must be a constructor).

Related

How do I use if-then-else statement with no else condition in Haskell?

I have a list of relations and I wish to print the names of all fathers. Since there's no else condition, the following code doesn't work:
relations = [("father", "arushi", "anandan"), ("mother", "arushi", "abigale"), ("father", "anandan", "ayuta"), ("mother", "anandan", "akanksha")]
father ((r, c, f):xs) = if r == "father" then print(f)
main = do
father (relations)
I do not wish to put any statement after else.
Too bad, all ifs come with elses. But that's okay, there's a distinguished do-nothing IO action.
father ((r, c, f):xs) = if r == "father" then print f else return ()
There are many other ways to skin this cat. One is pattern matching.
father (("father", c, f):xs) = print f
father ((r, c, f):xs) = return ()
Another that is specific to monadic actions is to use when.
father ((r, c, f):xs) = when (r == "father") (print f)
Of course, that's just hiding the else, which is again return ():
when p act = if p then act else pure () -- okay, it's actually pure, not return
The idiomatic Haskell way to solve such issues is to avoid mixing computation and I/O, when possible.
In this case, instead of "printing the names of all fathers", you can first "compute the names of all fathers" (no I/O here) and then "print the computed names" (I/O here)
relations =
[ ("father", "arushi", "anandan")
, ("mother", "arushi", "abigale")
, ("father", "anandan", "ayuta")
, ("mother", "anandan", "akanksha")
]
-- compute only the fathers
fathers = [ f | ("father", _, f) <- relations ]
-- print them
main :: IO ()
main = mapM_ putStrLn fathers
No if needed, since mapM_ iterates over the list for us, and all the list entries have to be printed.
Every if must have an else.
father ((r, c, f):xs) =
if r == "father"
then print f
else _what
If you try to compile that, you'll be informed that there's a hole
_what :: IO ()
So you need to manufacture something of that type. Fortunately, that's easy:
father ((r, c, f):xs) =
if r == "father"
then print f
else pure ()
pure x does nothing and returns x.
Since what you're trying to do is quite common, there are two functions specifically designed for the task:
when :: Applicative f => Bool -> f () -> f ()
when b m = if b then m else pure ()
unless :: Applicative f => Bool -> f () -> f ()
unless = when . not
You can find both of these functions in Control.Monad.
father ((r, c, f):xs) =
when (r == "father") $ print f
You can write a function that always writes the name, but then ensure it only gets called on values containing father.
relations :: [(String,String,String)]
relations = [("father", "arushi", "anandan")
,("mother", "arushi", "abigale")
,("father", "anandan", "ayuta")
,("mother", "anandan", "akanksha")
]
printName :: (String,String,String) -> IO ()
printName (_, _, name) = print name
printFathers :: [(String,String,String)] -> [IO ()]
printFathers = fmap printName . filter (\(f, _, _) -> f == "father")
main = sequence (printFathers relations)
The definition of filter hides the logic of skipping certain elements of the list. The argument to filter always returns either True or False, but the result of filter only contains those elements for which you want to call print.
(sequence, here, just turns the list of IO values into the single IO value that main must be by "swapping" IO and []. You could incorporate this into printName by defining it as sequence . fmap printName . ..., and replace sequence . fmap foo with traverse foo.)
Note that if foo then bar else baz is syntactic sugar for a complete case expression
case foo of
True -> foo
False -> baz
However, a case expression doesn't have to handle every possible value of the foo argument. You could write
father ((r, c, f):xs) = (case r of "father" -> print f) : father xs
It would be instructive, though, to see what happens when r doesn't match "father".
I feel the need to explain why an if must have an else in Haskell.
Haskell is an implementation of typed lambda calculus and in lambda calculus we have expressions and values nothing else.
In it we evaluate/reduce expressions to values or into expressions that can't be reduced any further.
Now in typed lambda calculus we add types and abstractions but we still to evaluate down to values and expressions one of these expressions being if predicate then value else value.
This if expression must reduce to a value therefore both branches of the if expression must reduce to values of the same type.
If we had an "if predicate then value" it means we would have a branch that doesn't reduce to a value.
you can use run, reduce and evaluate interchangeably in the context of this answer.
When we run Haskell code we are reducing lambda terms into values or expressions that can't be reduced any further.
The compiler exists to help us write valid lambda terms.
Going by lambda calculus we see that the if statement must, when evaluated, reduce to a value (or be capable of doing so) and because Haskell is implemented typed lambda calculus an if expression in Haskell without an else wouldn't have the possibility of evaluating down to a value all the time.
TL;DR
The "if ... then ... else" statement should when evaluated reduce to a value.
As long as both branches of the if statement evaluates to the same type it evaluates correctly.
If any branch doesn't evaluate to a value or are going to evaluate to values of different types that is not a valid lambda term and the code will not typecheck.
Was struggling with this style as well, & with Haskell formatting requirements. But I found that instead of placing emphasis on a required [else], one can use [else do] to include all following lines of code without an additional indention on concurrent lines, such as..
main = do
--if conditions exit main,
if t < 1 || t > 100000
then return ()
else
do
--code here, even with the else,
-- is only run when if condition above -> is false
Proof code can be in simpler form
if True
return ()
else
do
-- add code below this line to prove return works

Haskell: I don't know how to match types

So, I have this Haskell question to resolve:
Define a mapIO function that receives a function f and an input and output action a and results in an input and output action that, when executed, performs the given action a and returns the application of f to the return of a.
Here's my code:
mapIO f a = do b <- a
return f(b);
It compiles but it doesn't work. When I try to do the same as the following execution example, it doesn't work. Please, can someone help me?
Prelude Data.Char> mapIO even readLn
75
False
In many other languages, g(x) is the syntax for applying function g to argument x. In Haskell, juxtaposition suffices, so that g x applies g to x. By coincidence, this means g(x) is also valid syntax that applies g to the value (x), which is the same as x, so to a beginner it may seem that g(x) is the correct syntax for function application. But it ain't, and that confusion has bitten you here.
When you write return f(b), you probably assume this means to use the special syntax return and the thing to return should be the function application f(b). However, return is itself a function in Haskell. So what it actually means is to apply return to the function f, then apply the result to the term (b). (Function application is "left-associative" in that sense.)
Luckily the fix for function application associativity problems, as with other associativity problems, is to use parentheses. So:
return (f(b))
Or, without the coincidentally correct extra parentheses:
return (f b)
This leaves only the question of why it "worked" (in the sense of compiled and type-checked) in return f(b) form. This is a bit of an advanced topic; but it turns out that functions also form a Monad with return = const, and so return f(b) actually meant const f(b), which threw away the (b) term. (Aside: in addition to being allowed to use the function instance of Monad, we also must be using the function instance of Monad here. Since we are applying return f to (b), the type of return f must be a function.) So your definition was the same as:
mapIO' f a = do b <- a
f
That is: first do a, throw away its result, then do f as if it were another input/output action. If you check the type inferred for mapIO you will see it matches this intuition:
mapIO :: Monad m => m b -> m t -> m b
Whoops!

What's with the 'in' keyword?

In Haskell, why do you not use 'in' with 'let' inside of a do-block, but you must otherwise?
For example, in the somewhat contrived examples below:
afunc :: Int -> Int
afunc a =
let x = 9 in
a * x
amfunc :: IO Int -> IO Int
amfunc a = do
let x = 9
a' <- a
return (a' * x)
It's an easy enough rule to remember, but I just don't understand the reason for it.
You are providing expressions to define both afunc and amfunc. Let-expressions and do-blocks are both expressions. However, while a let-expression introduces a new binding that scopes around the expression given after the 'in' keyword, a do-block isn't made of expressions: it is a sequence of statements. There are three forms of statements in a do-block:
a computation whose result is bound to some variable x, as in
x <- getChar
a computation whose result is ignored, as in
putStrLn "hello"
A let-statement, as in
let x = 3 + 5
A let-statement introduces a new binding, just as let-expressions do. The scope of this new binding extends over all the remaining statements in the do-block.
In short, what comes after the 'in' in a let-expression is an expression, whereas what comes after a let expression is a sequence of statements. I can of course express a computation of a particular statement using a let-expression, but then the scope of the binding would not extend beyond that statement to statements that follow. Consider:
do putStrLn "hello"
let x = 3 + 5 in putStrLn "eight"
putStrLn (show x)
The above code causes the following error message in GHC:
Not in scope: `x'
whereas
do putStrLn "hello"
let x = 3 + 5
putStrLn "eight"
putStrLn (show x)
works fine.
You can indeed use let .. in in do-notation. In fact, according to the Haskell Report, the following
do{let decls; stmts}
desugars into
let decls in do {stmts}
I imagine that it is useful because you might otherwise have to have some deep indentation or delimiting of the "in"-block, going from your in .. to the very end of the do-block.
The short answer is that Haskell do blocks are funny. Haskell is an expression-based language—except in do blocks, because the point of do blocks is to provide for a "statement" syntax of sorts. Most "statements" are just expressions of type Monad m => m a, but there are two syntaxes that don't correspond to anything else in the language:
Binding the result of an action with <-: x <- action is a "statement" but not an expression. This syntax requires x :: a and action :: Monad m => m a.
The in-less variant of let, which is like an assignment statement (but for pure code on the right hand side). In let x = expr, it must be the case that x :: a and expr :: a.
Note that just like uses of <- can be desugared (in that case, into >>= and lambda), the in-less let can always be desugared into the regular let ... in ...:
do { let x = blah; ... }
=> let x = blah in do { ... }

Haskell Monad bind operator confusion

Okay, so I am not a Haskell programmer, but I am absolutely intrigued by a lot of the ideas behind Haskell and am looking into learning it. But I'm stuck at square one: I can't seem to wrap my head around Monads, which seem to be fairly fundamental. I know there are a million questions on SO asking to explain Monads, so I'm going to be a little more specific about what's bugging me:
I read this excellent article (an introduction in Javascript), and thought that I understood Monads completely. Then I read the Wikipedia entry on Monads, and saw this:
A binding operation of polymorphic type (M t)→(t→M u)→(M u), which Haskell represents by the infix operator >>=. Its first argument is a value in a monadic type, its second argument is a function that maps from the underlying type of the first argument to another monadic type, and its result is in that other monadic type.
Okay, in the article that I cited, bind was a function which took only one argument. Wikipedia says two. What I thought I understood about Monads was the following:
A Monad's purpose is to take a function with different input and output types and to make it composable. It does this by wrapping the input and output types with a single monadic type.
A Monad consists of two interrelated functions: bind and unit. Bind takes a non-composable function f and returns a new function g that accepts the monadic type as input and returns the monadic type. g is composable. The unit function takes an argument of the type that f expected, and wraps it in the monadic type. This can then be passed to g, or to any composition of functions like g.
But there must be something wrong, because my concept of bind takes one argument: a function. But (according to Wikipedia) Haskell's bind actually takes two arguments! Where is my mistake?
You are not making a mistake. The key idea to understand here is currying - that a Haskell function of two arguments can be seen in two ways. The first is as simply a function of two arguments. If you have, for example, (+), this is usually seen as taking two arguments and adding them. The other way to see it is as a addition machine producer. (+) is a function that takes a number, say x, and makes a function that will add x.
(+) x = \y -> x + y
(+) x y = (\y -> x + y) y = x + y
When dealing with monads, sometimes it is probably better, as ephemient mentioned above, to think of =<<, the flipped version of >>=. There are two ways to look at this:
(=<<) :: (a -> m b) -> m a -> m b
which is a function of two arguments, and
(=<<) :: (a -> m b) -> (m a -> m b)
which transforms the input function to an easily composed version as the article mentioned. These are equivalent just like (+) as I explained before.
Allow me to tear down your beliefs about Monads. I sincerely hope you realize that I am not trying to be rude; I'm simply trying to avoid mincing words.
A Monad's purpose is to take a function with different input and output types and to make it composable. It does this by wrapping the input and output types with a single monadic type.
Not exactly. When you start a sentence with "A Monad's purpose", you're already on the wrong foot. Monads don't necessarily have a "purpose". Monad is simply an abstraction, a classification which applies to certain types and not to others. The purpose of the Monad abstraction is simply that, abstraction.
A Monad consists of two interrelated functions: bind and unit.
Yes and no. The combination of bind and unit are sufficient to define a Monad, but the combination of join, fmap, and unit is equally sufficient. The latter is, in fact, the way that Monads are typically described in Category Theory.
Bind takes a non-composable function f and returns a new function g that accepts the monadic type as input and returns the monadic type.
Again, not exactly. A monadic function f :: a -> m b is perfectly composable, with certain types. I can post-compose it with a function g :: m b -> c to get g . f :: a -> c, or I can pre-compose it with a function h :: c -> a to get f . h :: c -> m b.
But you got the second part absolutely right: (>>= f) :: m a -> m b. As others have noted, Haskell's bind function takes the arguments in the opposite order.
g is composable.
Well, yes. If g :: m a -> m b, then you can pre-compose it with a function f :: c -> m a to get g . f :: c -> m b, or you can post-compose it with a function h :: m b -> c to get h . g :: m a -> c. Note that c could be of the form m v where m is a Monad. I suppose when you say "composable" you mean to say "you can compose arbitrarily long chains of functions of this form", which is sort of true.
The unit function takes an argument of the type that f expected, and wraps it in the monadic type.
A roundabout way of saying it, but yes, that's about right.
This [the result of applying unit to some value] can then be passed to g, or to any composition of functions like g.
Again, yes. Although it is generally not idiomatic Haskell to call unit (or in Haskell, return) and then pass that to (>>= f).
-- instead of
return x >>= f >>= g
-- simply go with
f x >>= g
-- instead of
\x -> return x >>= f >>= g
-- simply go with
f >=> g
-- or
g <=< f
The article you link is based on sigfpe's article, which uses a flipped definition of bind:
The first thing is that I've flipped the definition of bind and written it as the word 'bind' whereas it's normally written as the operator >>=. So bind f x is normally written as x >>= f.
So, the Haskell bind takes a value enclosed in a monad, and returns a function, which takes a function and then calls it with the extracted value. I might be using non-precise terminology, so maybe better with code.
You have:
sine x = (sin x, "sine was called.")
cube x = (x * x * x, "cube was called.")
Now, translating your JS bind (Haskell does automatic currying, so calling bind f returns a function that takes a tuple, and then pattern matching takes care of unpacking it into x and s, I hope that's understandable):
bind f (x, s) = (y, s ++ t)
where (y, t) = f x
You can see it working:
*Main> :t sine
sine :: Floating t => t -> (t, [Char])
*Main> :t bind sine
bind sine :: Floating t1 => (t1, [Char]) -> (t1, [Char])
*Main> (bind sine . bind cube) (3, "")
(0.956375928404503,"cube was called.sine was called.")
Now, let's reverse arguments of bind:
bind' (x, s) f = (y, s ++ t)
where (y, t) = f x
You can clearly see it's still doing the same thing, but with a bit different syntax:
*Main> bind' (bind' (3, "") cube) sine
(0.956375928404503,"cube was called.sine was called.")
Now, Haskell has a syntax trick that allows you to use any function as an infix operator. So you can write:
*Main> (3, "") `bind'` cube `bind'` sine
(0.956375928404503,"cube was called.sine was called.")
Now rename bind' to >>= ((3, "") >>= cube >>= sine) and you've got what you were looking for. As you can see, with this definition, you can effectively get rid of the separate composition operator.
Translating the new thing back into JavaScript would yield something like this (notice that again, I only reverse the argument order):
var bind = function(tuple) {
return function(f) {
var x = tuple[0],
s = tuple[1],
fx = f(x),
y = fx[0],
t = fx[1];
return [y, s + t];
};
};
// ugly, but it's JS, after all
var f = function(x) { return bind(bind(x)(cube))(sine); }
f([3, ""]); // [0.956375928404503, "cube was called.sine was called."]
Hope this helps, and not introduces more confusion — the point is that those two bind definitions are equivalent, only differing in call syntax.

Pattern matching in a let expression

How do you extract a value from a variable of an unknown constructor?
For instance, I would like to negate the value in an Either if was constructed as a Right:
let Right x = getValue
in Right (negate x)
This code successfully binds Right's value (an Int in this case) to x.
This works, but what if getValue returns a Left instead? Is there a way to determine the type of a variable in a let expression? Or is there a better way to approach this problem?
In general, what you can do is this:
case getValue of
Right x -> Right $ negate x
e -> e
What this does should be clear: it's just like pattern matching in a function argument, but against a value. To do what you need, you have a default case which catches anything not matched, and then return that.
In your particular case, however, you can do something slightly nicer:
negate `fmap` getValue
Or, with import Control.Applicative, you can use <$> as a synonym for fmap (negate <$> getValue). The fmap function has type fmap :: Functor f => (a -> b) -> f a -> f b. For any functor1, fmap converts a function on ordinary values to a function within the functor. For instance, lists are a functor, and for lists, fmap = map. Here, Either e represents a functor which is either an exception Left e or a value Right a; applying a function to a Left does nothing, but applying a function to a Right applies it within the Right. In other words,
instance Functor (Either e) where
fmap _ (Left l) = Left l
fmap f (Right r) = Right $ f r
Thus the case version is the direct answer to your question, but your particular example is more nicely approximated by fmap.
1: To a first approximation, functors are "containers". If you're not comfortable with the various type classes, I recommed the Typeclassopedia for a comprehensive reference; there are many more tutorials out there, and the best way to get a feel for them is to just play with them. However, the fmap for specific types is often readily usable (especially, in my opinion, when written <$>).
Answer to the title of this question:
I don't see big difference between "... where" and "let ... in ...". Both allows you do declare several cases of function argument bindings:
f val = let negR (Right x) = Right (negate x)
negR y = y
in negR val
or
let { negR (Right x) = Right (negate x); negR y = y; } in negR val

Resources