
Swift Functors, Applicatives, and Monads in Pictures - mokagio
http://mokacoding.com/blog/functor-applicative-monads-in-pictures
======
skybrian
If functional languages had called them the Mappable, Applicable, and
FlatMappable interfaces, and used map(), apply(), and flatMap() instead of
operators, it would have avoided a lot of confusion. But I guess that's how
you avoid success at all costs.

~~~
jerf
Honest question: Is there a reason 'flatmap' is any better other than it is
what you learned it as somewhere?

I'm not convinced English has a word or convenient phrase for "monad", and it
doesn't strike me that "flatMap" is it. How do I "flatMap" Haskell's STM
monad? Or a probability monad? (I know the mechanics of the answer, I am
specifically referring to the English-induced intution.) I don't see the
intuition being particularly correct; flatMap is really tied to List, which
isn't a particularly great thing to be tied to since it isn't very used.
List's monadic interface is cute for some little algorithms, sure, which makes
it disproportionately appear in examples, but list's monad implementation has
complexity O(m^n) (where m is the size of the lists and n the number of lists
you're going to consider) and you need some algorithm that gives you some
_serious_ culling on that before it's practical for very much.

~~~
dragonwriter
> flatMap is really tied to List

Its tied to _collections_ , not specifically to List. A number of (but
certainly not all!) important monads are (or can be viewed as) collections,
including Optional/Maybe (which can be viewed as a collection with cardinality
restricted to being either 0 or 1.)

~~~
jbooth
Follow-on question, are there any useful monadic constructs _not_ tied to
collections (including optional as you said)?

~~~
tel
Silly and wonderful there is always

    
    
        data Fake a = Fake
    

which is trivially a monad

    
    
        instance Monad Fake where
          return _ = Fake
          Fake >>= f = Fake
    

yet it clearly contains nothing.

~~~
lmm
Grandparent asked for _useful_ though :P

~~~
tel
Who says Fake isn't useful? It's very useful for stating that nothing can
happen :)

------
sleepychu
I appreciate that this article is just a quick code snippet rewrite but it
really could have done with some quick (even if ugly) edits on the graphics
and as a result ditched all the Haskell asides.

Assuming of course that I'm correct in my assumption that the articles is
aimed at Swifties looking at FAM and not Haskellers looking at Swift.

------
efnx
People often complain about Haskell syntax and operators looking ugly (I
disagree) but dang:

    
    
        func <^><T, U>(f: T -> U, a: T?) -> U? {
            return a.map(f)
        }
    

Gnartown!

~~~
CookWithMe
What is so ugly about it? Swift tries to be somewhat close to the usual
C-syntax (it's supposed to be the successor of Obj-C, after all).

For someone used to C-syntax, I guess the main deviation is that the return
type is in the back and that there's a func keyword. As for the operaters,
there is the addition of generics (what is wrong about <> ?), -> to describe
signature of a function (a very sensible choice IMO) and ? for Optionals
(again, fine for me).

I don't really see how a statically typed language can substantially improve
this, but I'd be happy if someone can proof me wrong :-)

~~~
kittenfluff
It's not clear to me why it's necessary to include <T, U> at the start of the
function definition. In Haskell, unquantified type variables are implicitly
universally quantified, i.e. you assume that the signature must be valid for
any types T and U.

That's the only thing I think could be substantially improved, though.
Personally I find the style where you separate the type signature from the
function definition easier to read, for example

How about

    
    
        <^> : (T -> U) * T? -> U?
        <^> (f, a) {
            return a.map(f)
        }
    

or even

    
    
        <^> : (T -> U) * T? -> U?
        <^> (f, a) -> a.map(f)
    

which is already pretty close to the Haskell equivalent

    
    
        (<^>) :: (t -> u) -> Maybe t -> Maybe u
        (<^>) = fmap
    

Arguably, Haskell syntax could be improved with more built-in syntax

    
    
        <^> : (t -> u) -> t? -> u?
        <^> = fmap
    

though I haven't thought about what this means for parsing the language.

~~~
lmm
Explicit is better than implicit. Does Haskell allow functions to have value
parameters that aren't declared?

~~~
TheCoelacanth
Depends what you mean by "not declared". Haskell doesn't require you to
provide type signatures, so if you don't put a type signature on a function,
you can have parameters that aren't explicitly declared (though they still
have an inferred static type, so you could use ghci to see what all the
parameters are). If you do put any type signature on the function, then all
parameters would have to be included.

~~~
lmm
If I make a typo when using a value parameter in a function definition, can I
accidentally introduce an extra value parameter?

If I make a typo when using a type parameter in a function definition, can I
accidentally introduce an extra type parameter?

~~~
TheCoelacanth
> If I make a typo when using a value parameter in a function definition, can
> I accidentally introduce an extra value parameter?

No.

> If I make a typo when using a type parameter in a function definition, can I
> accidentally introduce an extra type parameter?

You couldn't introduce a new concrete type. You could introduce a new type
variable, but the type signature would still have to typecheck, so it would
difficult to come up with a non-contrived example where that would happen.

------
FeepingCreature

        let post = Post.findByID(1)
        if post != nil {
          return post.title
        } else {
          return nil
        }
    

Or, as a cool C-like would put it:

    
    
        let post = Post.findByID(1)
        return post?.title
    

Just saying!

~~~
octocoupler
That is how it's done in Swift. Are you saying there are C languages that do
the same thing?

~~~
FeepingCreature
Well, mine does (
[https://github.com/FeepingCreature/fcc](https://github.com/FeepingCreature/fcc)
). I don't think it's very widespread, sadly.

Example:
[https://github.com/FeepingCreature/fcc/blob/master/tests/tes...](https://github.com/FeepingCreature/fcc/blob/master/tests/test69.nt)

~~~
octocoupler
Nice! If you want it to be, you should add some information and examples. Or a
simple website, even.

~~~
FeepingCreature
No I mean the syntax. :)

For my language, I'll do some proper advertising on it once I figure out
version two; v1 is very much a testbed for playing around with language
design.

------
coldcode
Interesting. And people think Swift is easy to learn. Not all of it though.

~~~
hellofunk
Swift itself is quite easy to learn, and you don't actually have to do any
functional programming in it if you don't know how to do so. I'll bet most
people writing in Swift are doing little more than they would have done in
Objective-C since it fully supports the OO paradigm. Over time, more and more
will adopt some of the neat things you can do with this first-class functions.

------
superfunc
I was expecting a Chipotle menu

------
panic
Why even have the concept of a monad in Swift? The language is neither lazy
nor purely functional, so the problem monads were introduced to solve doesn't
exist. You can just write regular code to do I/O.

~~~
Retra
Monads exist regardless of whether you call them that. They are a mathematical
idea. An algebraic structure.

If you made a language that used conditionals based on 1 and 0, it could do
_boolean logic_ , even if you didn't include boolean values explicitly.

Monads exist in just about every programming language. They weren't introduced
to solve a problem. They already existed, and just happen to be useful to
solve certain problems.

~~~
woah
I've read that synchronously executed code from a text file is actually a form
of monad in itself. Is this true?

~~~
lmm
Sequences of bytes form a monad. Sequences of machine instructions form a
monad. (Indeed, for any x, sequences of x form a monad). This is occasionally
a useful fact (e.g. it's what tells you that you can debug an assembly program
by debugging the first half, then debugging the second half starting from the
state it was in at the end of the first half).

The definition of a monad is really simple - a lot of things form monads.
Which is what makes them so powerful, because if you write a function that
works _on a generic monad_ , you find you can use that function for a lot of
things.

