Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does `fmap sum Just` typecheck?

We know fmap is fmap :: Functor f => (a -> b) -> f a -> f b and sum is sum :: (Num a, Foldable t) => t a -> a, but the code below confuse me.

> :t (fmap sum Just)
(fmap sum Just) :: Num b => b -> b
> fmap sum Just 3
3

why?

like image 824
Jimmy Hu Avatar asked Apr 10 '17 03:04

Jimmy Hu


People also ask

When to use FMAP in Python?

You can fmap whatever you want, as long as there’s a Functor instance for its type. This is extremely powerful, because it allows us to push complexity from the caller to the callee. From now on, I’m going to use fmap exclusively in my own code: Code that’s using more generalized functions is easier to reuse and change later on.

How to specify the type of the arguments in JavaScript?

Use JSDoc var-arg syntax to specify the type of the arguments. Since there is no natural syntax for specifying generic type parameters in JavaScript, an unspecified type parameter defaults to any.

Why do generic functions default to default type parameters?

A call to a generic function uses the arguments to infer the type parameters. Sometimes this process fails to infer any types, mainly because of lack of inference sources; in these cases, the type parameters will default to any. For example: To learn all of the features available in JSDoc, see the reference.


1 Answers

I think there are probably two confusing bits here.

The first, most obvious, is that sum works on Foldable things, not just lists. Therefore:

sum (Just 3) == 3

The second is the functor instance you are using. Since Just is a function, as that is the second argument to fmap, you are using the reader instance of fmap, which is defined here (https://hackage.haskell.org/package/base-4.9.1.0/docs/src/GHC.Base.html#line-638) as simply (.).

It looks weird, and like it shouldn't type-check, because you are supplying three arguments to fmap, but actually, the result of the (fmap sum Just) is a function:

Prelude> :t fmap sum Just
fmap sum Just :: Num b => b -> b  

If we replace fmap with ., things start to make a little more sense.

Prelude> (.) sum Just 3
3

Prelude> (sum . Just) 3
3

Which is the same as

sum (Just 3)
like image 181
Adam Wagner Avatar answered Oct 11 '22 19:10

Adam Wagner