I was looking at Alternative
typeclass in haskell and I was playing with it in ghci when I issued this
some (Just 2)
It hanged, I looked in the source code of Alternative, Alternative's some and many default definition is this :
some :: f a -> f [a]
some v = some_v
where
many_v = some_v <|> pure []
some_v = (fmap (:) v) <*> many_v
-- | Zero or more.
many :: f a -> f [a]
many v = many_v
where
many_v = some_v <|> pure []
some_v = (fmap (:) v) <*> many_v
It's obvious that some_v
and many_v
are indirectly infinitely recursive, and they aren't defined in terms of empty
and <|>
.
If they must be defined by the instance then they shouldn't have default definition, right ? and since Maybe
doesn't define them my statement above hanged which seems strange to me since it isn't mentioned in the docs.
So why were they defined like that ? is There something I'm missing ?
The Alternative instance for Maybe is as follows:
It defines
empty
and(<|>)
, leavingsome
andmany
as their default implementations.Using
many
andsome
makes sense when theAlternative
can succeed or fail for "external reasons" not contained in the value itself. The typical example is parsers: you try to parse integers repeatedly from an input stream, until an integer isn't found andempty
is returned.But with
Just 2
, the Alternative "always succeeds", so to speak. There's nothing external to the value that can make it "fail" and finish the computation. So it goes into an infinite loop.