# Sequence detection in Haskell?

I am trying to compile a fairly simple haskell program. Either I don’t know how to arrange expressions (expressions) in Haskell, or there’s no way to do it.

I need a function like:

```
f = <do stuff 1>
<do stuff 2>
...
```

supposed to simulate a template

```
<do stuff>
<tail recursion>
```

but failed to compile:

```
go 0 = 0
go i = case i of
1 -> 2
_ -> 3
go (i-1)
```

This doesn't work either (easier, no recursion):

```
go i = 1
2
```

The code is directly above compilation, but while working I get cryptic information:

```
No instance for (Num (a0 -> t0))
arising from a use of `go'
Possible fix: add an instance declaration for (Num (a0 -> t0))
In the expression: go 2
In an equation for `it': it = go 2
```

I have a problem with indentation? Incorrect sequence problem? Or is there no sequencing capability? If there is no consistency, how would you directly do

```
<do stuff>
<tail recursion>
```

?

Thanks for answers.

It's hard to believe that a function in Haskell is mostly limited to one "expression" or "statement" or whatever you want to call it. How would you solve the following contrived toy example (written in erlang, but could easily be translated into prologue or a whole host of other languages):

```
count([], X) -> X;
count([_|B], X) ->
Y = X+1,
count(B, Y).
```

Example:

```
erlang> count([a,b,c,d,e],0).
5
```

The second sentence follows the pattern I described earlier:

```
<do stuff>
<tail recursion>
```

I'm assuming this particular example maps to Haskell the "let ... in" described here. But what if there should be 10 "doing things", or 20 or more? And this "let ... in" is guaranteed to be a tail recursive (the given example is guaranteed to be in erlang, prologue, schema, etc.).

Is there a way that I can just "group" or "order" a bunch of statements or expressions? In prologue or erlang, the sequence is executed with a comma (see the toy example above). In c / C ++, this is achieved with a semicolon. I thought the Haskell operator was just whitespace, but maybe it just isn't done in this language?

source to share

In Haskell, you don't write functions that "do things". You write functions that compute a value. In this light, it makes no sense to structure the function the way you suggest:

```
f = <do stuff 1>
<do stuff 2>
```

Instead, you write the actual math-y function, which is the only expression that depends on certain inputs:

```
f x y = blah x blah y blah
```

It might be convenient to break it down into subexpressions

```
f x y = res1 + res2
where res1 = x * 3
res2 = y + 4
```

But in the end, it's just one expression.

Monodeficient code written in a note `do`

may appear to "do things" sequentially:

`f = do thing1 thing2`

But this is just an illusion. It also contains one expression:

```
f = thing1 >> thing2
```

This expression indicates that `f`

is a value that is a composition `thing1`

and `thing2`

. Now IO code can compile code that "makes stuff" consistently, but that's not what it means in Haskell. In Haskell, it's not just "doing things". Instead, you compose.

source to share

It's great that you were able to provide some sample Erlang code for what you mean by "doing things". So far, this has been a little vague. While we are talking only about strict languages, in this case one can be somewhat vague, since the rules are quite uniform and understandable.

On the other hand, we are talking about Haskell, a lazy-evaluated language, so it is good to have an idea of what it means to "do things", otherwise there can be confusion due to incorrect assumptions.

Here's a straightforward translation of the Erlang function you provided in Haskell:

```
count ([],x) = x
count (_:b, x) =
let y = x + 1
in count (b, y)
```

As you can see, it is almost identical in structure to the Erlang version. So you might be wondering what's the big deal? If it's so easy to "do something" in Haskell, then why is everyone making it sound so complicated?

One way to explain what a big deal is is to point out that the above Haskell function is equivalent to this:

```
count ([],x) = x
count (_:b, x) = count (b, x + 1)
```

Also this one:

```
count ([],x) = x
count (_:b, x) = count (b, y) where y = x + 1
```

This is because the order in which Haskell expressions are evaluated is independent of the lexical order of those expressions. In general, Haskell will delay expression evaluation until the last moment.

Now when you think about putting together this lazy evaluation scheme along with side effects (reading or writing files, sending output to the screen, etc.), it gets a little fuzzy. The order in which side effects occur is usually very important. Fortunately, functions in Haskell that deal with side effects don't do side effects themselves at all. Rather, they create an "action" meaning that describes a side effect. Then there are other functions that can compose these "action" values in such a way that the order is respected. Then you just need something that will actually perform the side effects described by the "action" values ...

source to share

Basically, there is no way to do this. Haskell is a purely functional language, there is no change or order of statements. Monads are one way to mimic a sequence. There are many tutorials on the internet, I personally advise you to read the chapters of the "Teach You" monad Haskell For Great Good! or Real World Haskell . Another thing: sequential operations are not very idiomatic in Haskell. You'd better start somewhere else.

source to share

When you say "do things" what do you mean?

- compute something, transform the data that we already have?
- interact with the user, read / write a file, download something from the internet?

In the first case, use `let`

... `in`

:

```
quadraticRoots a b c = let discriminant = b * b - 4 * a * c
root = sqrt discriminant
in case compare discriminant 0 of
LT -> []
EQ -> [-b / (2 * a)]
GT -> [(-b + root) / (2 * a), (-b - root) / (2 * a)]
```

In the second case, use the notation `do`

:

```
main = do args <- getArgs
case map read args of
[a, b, c] -> putStrLn $ case quadraticRoots a b c of
[] -> "no real roots"
[x] -> "single root: " ++ show x
[x1, x2] -> unwords ["two real roots:", show x1,
"and", show x2]
_ -> hPutStrLn stderr "Please provide three coefficients on the command line"
```

source to share

**Update:** Be careful not to write Scheme programs in Haskell. Cumulative parameters are rare in idiomatic Haskell, which uses laziness rather than tail recursion.

For example, a definition `count`

in Haskell would resemble

```
count [] = 0
count (x:xs) = 1 + count xs
```

You might argue that the source `length`

looks more like Scheme-ish

```
-- | /O(n)/. 'length' returns the length of a finite list as an 'Int'.
-- It is an instance of the more general 'Data.List.genericLength',
-- the result type of which may be any kind of number.
length :: [a] -> Int
length l = len l 0#
where
len :: [a] -> Int# -> Int
len [] a# = I# a#
len (_:xs) a# = len xs (a# +# 1#)
```

but this is low-level, non-idiomatic code. The link `genericLength`

has the same structure as `count`

above and has wider applicability compared to `length`

.

```
genericLength :: (Num i) => [b] -> i
genericLength [] = 0
genericLength (_:l) = 1 + genericLength l
```

"Do it, then do it" in Haskell is expressed as a compound function in clean code. For example, to compute the length of the longest sublist, compute the lengths of the subscriptions, and then the maximum over those lengths. In Haskell, this is expressed

```
Prelude> :t maximum . map length
maximum . map length :: [[a]] -> Int
```

or

```
Prelude> :m + Data.List
Prelude Data.List> :t maximum . map genericLength
maximum . map genericLength :: (Ord c, Num c) => [[b]] -> c
```

Note: Laziness adds nuance, but the common point is there.

Even in "imperative" code inside `IO`

, for example

```
main :: IO ()
main = do
putStr "Hello "
purStrLn "world!"
```

is a composition of functions under the covers as it has the same semantics as

```
main :: IO ()
main = putStr "Hello " >>= \_ -> putStrLn "world!"
```

Perhaps an example that uses the list monad would make this clearer. Let's say we want all Pythagorean triples to be `(a,b,c)`

such that no component is greater than some maximum n.

```
import Control.Monad (guard)
triples :: Integer -> [(Integer,Integer,Integer)]
triples n = do
a <- [1 .. n]
b <- [a .. n]
c <- [b .. n]
guard $ a*a + b*b == c*c
return (a,b,c)
```

As you can see, we have to select the candidate value first `a`

, then `b`

, etc.

The compiler converts this code to explicitly use the `>>=`

monadic bind combinator.

```
-- indented to show nested scopes
triples_bind :: Integer -> [(Integer,Integer,Integer)]
triples_bind n =
[1 .. n] >>= \a ->
[a .. n] >>= \b ->
[b .. n] >>= \c ->
(guard $ a*a + b*b == c*c) >>= \_ ->
return (a,b,c)
```

Inside the monad of the list `>>=`

is `concatMap`

, so the above matches

```
triples_stacked :: Integer -> [(Integer,Integer,Integer)]
triples_stacked n =
concatMap (\a ->
concatMap (\b ->
concatMap (\c ->
concatMap (\_ ->
[(a,b,c)])
(guard $ a*a + b*b == c*c))
[b .. n])
[a .. n])
[1 .. n]
```

The indentation shows structure and is nice because it gives the impression of a Haskell logo that combines λ with `>>=`

.

Another way to express the same semantics:

```
triples_cm n = concatMap step2 [1 .. n] -- step 1
where step2 a = concatMap step3 [a .. n]
where step3 b = concatMap step4 [b .. n]
where step4 c = concatMap step5 (guard $ a*a + b*b == c*c)
where step5 _ = [(a,b,c)]
```

Haskells pattern matching is already doing the `case`

matching behind the scenes. Instead

```
go 0 = 0
go i = case i of
1 -> 2
_ -> 3
go (i-1)
```

complete the started template.

```
go 0 = 0
go 1 = go (2 - 1)
go _ = go (3 - 1)
```

Remember that variables in Haskell are immutable: they are not destructively updated like in C or Java. You get one chance to figure out the value of the variables, and then you get stuck with it. Instead, you can define `go`

as

```
go 0 = 0
go x = let i = case x of 1 -> 2
_ -> 3
in go (i - 1)
```

or

```
go 0 = 0
go x | x == 1 = go (2 - 1)
| otherwise = go (3 - 1)
```

The examples above all typecheck, but have the same big problem, namely that it `go`

only completes when its argument is zero. You have not provided enough information for us to help with this issue. Tell us what you are trying to do and we can offer specific guidance for your situation.

source to share

I'm not sure what is correct what your function should do. Maybe you want something like this:

```
go :: Int -> Int
go 0 = 0
go i = go (i-1)
```

if this function takes an argument, eg. '3' he calculates go 3 → go 2 → go 1 → go 0 → 0 and gets the answer "0"

Now, if you want to execute a sequence, you can use the 'do' keyword, but I'm sure this is what you need now. If you are trying to create any "variables", look at the "let" and "in" expressions:

```
someInput = 7
gogogo 0 = 0
gogogo n =
let
gavk = n + 1
kravk = gavk * 2
out = kravk + 1
in
out
main =
do
putStrLn "this is sample do statement"
putStrLn "gogogo:"
putStrLn $ gogogo someInput
```

UPD. edited errors

source to share