Thread: Can you count to ten?

1. Code:
`main = foldr((>>) . putStrLn . show)(return ())([1 .. 10]);`
Thats the most ugly code I've ever seen. If I didn't know it prints 1 to 10 then I'd be lost in days of analysis trying to figure it out. Sucks. Whats wrong with just

Code:
`[1 .. 10]`
Also WTF is the return() HAH who ever writes this crap?

2. BBC Basic

Code:
```REM 1-10 printing
REM ===================
FOR i = 1 TO 10
PRINT i
NEXT i
ENDPROC
END```

3. Originally Posted by MacNilly
Code:
`main = foldr((>>) . putStrLn . show)(return ())([1 .. 10]);`
Thats the most ugly code I've ever seen. If I didn't know it prints 1 to 10 then I'd be lost in days of analysis trying to figure it out. Sucks. Whats wrong with just

Code:
`[1 .. 10]`
Also WTF is the return() HAH who ever writes this crap?
4. Weeks.

This took me 4 weeks to figure out lol XD

It is very ugly but let me explain, the foldr signature is :
Code:
`foldr :: (a -> b -> b) -> b -> [a] -> b`
I'm using `[a]` instead of traversable `t a` for simplicity.

foldr is somewhat intuitive in that it folds from right to left. Using this and the above type signature, we can infer that first part of our fold is
Code:
`(>>) . putStrLn . show \$ 10`
which gives us a partially applied monadic sequence operation. Using the `b` part of our signature, this is then applied to `return ()` which just gives us an empty monad instance.

So basically, what we wind up with is this:
Code:
`... (8 >> (9 >> (10 >> IO())))`
Remember that
Code:
`m >> k = m >>= \_ -> k`

So you wind up with (let's pretend we don't need the show crap and we're only going 1 through 5):
Code:
`putStrLn("1") >> (putStrLn("2") >> (putStrLn("3") >> (putStrLn("4") >> ((putStrLn("5") >> return ())))))`
Long-story short, this is why Haskell is stupid and isn't used in the industry and no amount of hipster nonsense (credit to Yarin for the hipster term ;P) can ever hope to make it a practical and viable programming language.

However, learning category theory has done nothing but make me a better programmer.

Edit:

Some of the stuff is just there because Haskell has a decent type system. If we have a number, we need to Show it first and then when we putStrLn, we simply get a monad back out. Because we want to sort of chain these guys together, it's easiest to fold using a sequence which does our >>= stuff for us. Basically, we want to map over the list creating an IO instance of each element and then we want to chain them together. This is most easily expressed as a fold with a monadic sequencing.

Something something functors something something applicative, no one understands my code, god, Mom!

4. You would make a good Java programmer, John

5. What makes you say that?

7. Lol I literally just started reading about how in categorical terms an applicative is actually a monoidal functor. I think everything in Haskell is enterprise-quality by nature of the beast XD

Seriously, the most useless thing ever but I can't pull myself away from it!

8. Well, in procedural terms an applicative can be thought of as a function. So, you could say C++ is enterprise-quality.
The good thing about comparison theorems is that you can always think of an ant as type of elephant.

9. Heh heh. Not as much fun as the category theory version though :P

It's really fun to think about while I'm at work because Lord knows I can't focus on actual work that long.

10. Originally Posted by MutantJohn
However, learning category theory has done nothing but make me a better programmer.
Well there you go then. You found a use for Haskell after all

11. Well, I can see you "learned you some Haskell for some good". Bravo!

I mean, I like a lot of the concepts of Haskell, but when I hit monads I gave up. I understand that they adopted the monad concept in order to encapsulate side-effects in order to make Haskell "pure", but to me it just seems to be to be excessively difficult to apply and a basically useless abstraction. I mean, think about it: some side effect must have occurred, if any I/O is actually done. Then, the whole point of the monad type is to limit the amount of "damage" that these side effects have on the rest of the program. However, this could be done in other ways that are conceptually simpler. What about a language that had an "iterative" and "functional" subsets... and differentiated between "pure" functions and "side-effecting" functions, and these could only be used in certain contexts? I think it would achieve the same separation between pure/impure that is the whole point of the monad, without introducing the difficulties.

For example, you could have "functions" (pure) and "procedures" (impure), denoted by different keywords. While the majority of the program would be pure (disallowing "impure" procedure calls) you could have a "do" block that enters a iterative context, where you can freely mix assignment and procedure call. Actually, I am working on a language like this at the moment...

12. D actually supports a "pure" keyword. I wish C++ did too... :P

But yeah, the IO monad is basically a way of guaranteeing the same function execution, even if the input is different. Fundamentally, FP is about categories over types and how those types are transformed from one to the other. The type system does help keep things in line but that's more or less because it represents a functor and how functors transform categories.

13. Originally Posted by MutantJohn
D actually supports a "pure" keyword. I wish C++ did too... :P
It's not as useful as it seems. Purity is trivial to statically prove. And it doesn't help with CTFE, since if you want to guarantee it, the expression in question should be decorated as such, which C++ does have, in the form of constexpr.

14. Apl:
Code:
`⍳10`

15. Originally Posted by swgh
BBC Basic

Code:
```REM 1-10 printing
REM ===================
FOR i = 1 TO 10
PRINT i
NEXT i
ENDPROC
END```
This won't run in BBC BASIC since you haven't defined the procedure. Remove the ENDPROC and it will work - or define the procedure. This will work in BBC BASIC for Windows:

Code:
```      PROC_loop
PRINT
PRINT "THE END."
END

DEF PROC_loop
FOR I=1 TO 10
PRINT I;
NEXT I
ENDPROC```
...as will the REPEAT...UNTIL loop in BBC BASIC that I posted earlier on in this thread.