Morgen Yang
Morgen Yang

Reputation: 333

Why is 'Nothing' as output in ' do{ let{ the= Just "Hi!"}; _ <- sequence [the,Nothing]; pure "no way!" }'

Just like title, codes like below:

do{ let{ the= Just "Hi!"}; _ <- sequence [the,Nothing]; pure "no way!" }

The Output is Nothing. My question is how can I be sure, this Do-block is a Maybe-Monad? And what is exactly function of do as Syntactic sugar?

Upvotes: 0

Views: 106

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477190

My question is how can I be sure, this do-block is a Maybe-Monad?

You can perform type inference, just like the Haskell compiler does. In order to do that we first should desugar the do-notation, as described in the Haskell '10 report.

Your expression is equivalent to:

let the = Just "Hi!" in sequence [the,Nothing] >> pure "no way!"

So now that we know that, let us look at the types. It is clear that the is a the :: Maybe String, so that means that the list of [the, Nothing] has type [the, Nothing] :: [Maybe String].

The type of sequence is sequence :: (Traversable t, Monad m) => t (m a) -> m (t a), so that means that t is t ~ [] here, and that m ~ Maybe and a ~ String. With these type equivalences suquence in this example has type sequence :: [Maybe String] -> Maybe [String]. This thus means that sequence [the, Nothing] has type sequence [the, Nothing] :: Maybe [String].

The (>>) function has type Monad m => m a -> m b -> m b. Since the left operand of >> has type Maybe [String] this thus means that m ~ Maybe and a ~ String. The right operand is pure "no way!". pure has type pure :: Applicative f => a -> f a. We can derive that a ~ String here, and since the right operand needs to have type m b from the (>>) function type, this thus means that m b ~ f a, and hence that f ~ Maybe.

We thus can derive that the type of (>>) (sequence [the, Nothing]) (pure "No way!") is Maybe String.

what is exactly function of do as Syntactic sugar?

Syntactical sugar is used to make notation more convenient. For the above example, it probably does not matter that much. For some larger expressions, do will filter out some noise, because it hides the >>= operators in between statements, and furthermore the f >>= \x -> ... is written as x <- f; ... which makes it sometimes easier to track what variable is bounded to what expressions.

Upvotes: 5

Related Questions