I know I can use join to remove the first level of list
join [["dog"]] " output ["dog"]
But why the following is not working
join $ (Just ["dog"])
got error:
Couldn't match type ‘[]’ with ‘Maybe’
We know Maybe and [] are both Monad in Haskell,
join(Monad m)=> m(m a) -> m a
Maybe is Monad
[] is Monad
What is wrong with that?
It seems to me join only for the same type of Monad, please correct me if I'm wrong.
Is there any function similar to join for any Monads like the example I's given above?
I know I can do it as following
fromJust (Just ["dog"])
"output: ["dog"]
But I need to know Just in advance.
1 Answer 1
The m in join :: Monad m => m (m a) -> m a is the same Monad everywhere it appears. If you had Just (Just "dog"), then you have two Maybe monads and your join will work perfectly. Similarly to your list example.
Pulling things out of a Monad cannot be generalized, which is part of the power of Monads. Consider that if you could do that, it would be trivial to strip out the type safety of the IO Monad!
To go from Just ["dog"] -> ["dog"], you just need a Maybe a -> a You could use Data.Maybe.fromJust, but maybe is safer (what if you have Nothing instead?)
joindoesn't simply remove an outer monad; it merges them, in a monad-specific way. Evenjoin [["dog"]]doesn't simply remove the outer list; it concatenates the inner lists:join [["dog"], ["cat"]] == ["dog", "cat"].joinis defined as part of the definition of a Monad. Each Monad definesjoindifferently.