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:
instance Alternative Maybe where
empty = Nothing
Nothing <|> r = r
l <|> _ = l
It defines empty
and (<|>)
, leaving some
and many
as their default implementations.
Using many
and some
makes sense when the Alternative
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 and empty
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.