Hi folks, can anyone recommend a good article on f...
# arrow
t
Hi folks, can anyone recommend a good article on flatMap vs map? I'm finding that i'm almost always using map in my code and so suspect I'm missing something as I learn FP
s
They have different signatures and thus different powers. While
map
takes a function of the shape
(A) -> B
,
flatMap
takes a function of the shape
(A) -> Kind<F, B>
. If we look at this for
List
that means.
Copy code
listOf(1, 2, 3).map { it + 1 }
 // [2, 3, 4]

listOf(1, 2, 3).flatMap { listOf(it, it + 1) }
 // [1, 2, 2, 3, 3, 4, 4, 5]
With
flatMap
here we can return 2 items instead of 1 since we can return the result inside
List
. The same is true for all data types. For example with Option that means using `map`` I always return a value, but in case of
flatMap
I could also return
Option.None
.
πŸ™ 2
πŸ” 2
a
also ->
flatmap = map + flatten
πŸ‘Œ 2
πŸ™ 3
☝️ 3
t
Ahh okay that makes sense ... so I use flatMap when the lambda returns a nesting ... So, for example, if the lambda returned an Either I can use flat map to unpack the inner Ether so I don't end up with nested Eithers?
πŸ’― 3
s
Exactly!
t
great thanks :)
... and a few minutes later I needed flatMap πŸ™‚
πŸ˜‚ 1
s
I recommend this talk on the subject: https://fsharpforfunandprofit.com/rop/
πŸ” 3
t
thanks will add it to my list
a
You could also build your own
Option
and
Either
type. It's really simple, and looking at the implementation tells you how it works. This is the code for `Option`:
Copy code
sealed class Option<A> {
    abstract val value: A

    abstract fun <B> map(f: (A) -> B): Option<B>
    abstract fun <B> flatMap(f: (A) -> Option<B>): Option<B>

    class None<A>: Option<A>() {
        override fun <B> map(f: (A) -> B): Option<B> = None()
        override fun <B> flatMap(f: (A) -> Option<B>): Option<B> = None()
        override fun equals(other: Any?): Boolean {
            if (this === other) return true
            if (javaClass != other?.javaClass) return false
            return true
        }

        override val value: A
            get() = TODO("Not yet implemented")
    }

    data class Some<A>(val valueInput: A): Option<A>() {
        override fun <B> map(f: (A) -> B): Option<B> = Some(f(valueInput))
        override fun <B> flatMap(f: (A) -> Option<B>): Option<B> = f(valueInput)

        override val value: A
            get() = valueInput
    }

    companion object {
        operator fun <A> invoke(a: A? = null): Option<A> =
                when(a) {
                    null -> None()
                    else -> Some(a)
                }
    }
}
🀘🏼 1
Imagine you don't have
flatMap
and you tried to use
map
for a function with
(A) -> Option<A>
, you get
Option<Option<A>>
. You need to flatten that with
flatMap
to get
Option<A>
. Seeing a basic implementation will tell you a lot about its behavior.
πŸ™ 1
πŸ‘πŸΌ 1
t
Thanks for this. Ya I need to spend more time in the source code. Option makes a lot of sense. I'll dig into either tomorrow.
a
Arrow's source code could be a lot more complex, I have not looked. Anybody who wants to understand the concept of Arrow should read the book "The Joy of Kotlin", it's a fantastic intro book showing you how to build these types, understanding Lazy, what a
traverse
is. I am using ideas from this book to teach core FP concepts, and once the team feels comfortable, I'll pull out Arrow, as a great library that does (and many other things) for you.
t
I was about to ask if anyone had a book recommendation πŸ˜‚
a
☝️
I am halfway through the book, but it's eye opening. Here are the examples I have completed so far. I've built my own
Maybe
and
Either
in Haskell (for learning purposes) and the fact that you can do it in Kotlin with ease tells you a lot about the language. I wish more book examples would use TDD...
t
It's it a "pure" FP book?
One area that's unclear to me, is how mixing different paradigms is going to turn out!
a
I am not sure about "pureness", but it's the best book I've found so far describing FP principles.
t
I have lots of code that follows a more OO approach, and currently I can't imagine doing away with OO completely
From what you've read so far, does the book touch on that?
a
Whatever fits your team I think. The folks I am working with are scared of FP and the "complexity" of it. I am thinking of writing certain components (like API and dataaccess) in more object oriented style, but the "orchestration" logic is functional.
Tim, that's why included the examples from my GitHub account.
πŸ™ 1
t
Oh perfect I'm on my phone currently but will check it out tomorrow
a
Take a look at the "Table of Contents", look at the examples.
Nothing teaches you better than building a
traverse
function on an
Either
type yourself.
It's a demanding book, you must type in the examples in your editor and run them to understand them.
t
Thanks, that's useful to know
πŸ‘ 1
Okay just bought the book
πŸ˜‚ 1