I have the following type:
newtype Rep f a = Rep { runRep :: String -> f (String, a) }
The type Rep f a is a stateful computation that takes a String as the initial state and produces a (String, a) as the result of the computation. The result of the computation is wrapped in the functor f.
The Applicative instance for Rep is the following:
instance Monad f => Applicative (Rep f) where
pure x = Rep $ \s -> pure (s, x)
Rep f <*> Rep x = Rep $ \s -> do
(s',rf) <- f s
(s'',rx) <- x s'
return (s'', rf rx)
And the Monad instance for Rep is the following:
instance Monad f => Monad (Rep f) where
return x = pure x
Rep a >>= f = Rep $ \s -> do
(s', ya) <- a s
let (Rep f') = f ya
(s'', yf) <- f' s'
pure (s'', yf)
The Alternative instance for Rep is the following:
instance (Monad f, Alternative f) => Alternative (Rep f) where
empty = Rep (const empty)
Rep a <|> Rep b = Rep $ \s -> a s <|> b s
I have the following data types and function:
data TD = Empty | Fol TD TD | Letters [Char] | Str TD
data Res = Nil | Character Char | Cop Res Res | Special [Res]
findmatch :: (Monad f, Alternative f) => TD -> Rep f Res
findmatch (Str a) =
frontAdd <$> findmatch a <*> findmatch (Str a)
<|> pure (Special [])
where
frontAdd x (Special xs) = Special (x:xs)
frontAdd _ _ = error "Not possible."
I am having trouble understanding the function above. The function frontAdd creates a Special value which contains a list of [Res]. findmatch returns Rep f Res. The line frontAdd <$> findmatch a <*> findmatch (Str a) applies frontAdd to the Res that is returned by findmatch a and findmatch (Str a).
However, I am not sure how this line, with the pattern matching, works: frontAdd x (Special xs) = Special (x:xs). Further, assuming that the functor f is [ ], how would the <|> in frontAdd <$> findmatch a <*> findmatch (Str a) <|> pure (Special []) work? I know that if the functor f is Maybe, then <|> makes a left-biased choice, but I don't know how <|> works specifically for lists. In the documentation it states:
instance Alternative [] where
empty = []
(<|>) = (++) -- length xs + length ys = length (xs ++ ys)
How exactly does the concatenation work? Am I correct in saying that the result of frontAdd <$> findmatch a <*> findmatch (Str a) is concatenated with the empty list?
Any insights are appreciated.
First, if
fis[], thenpure (Special [])is[(Special [])], which is just[Special []].Second, list concatenation is the most natural thing, with
i.e.
which is to say,
Thus
and
So no,
<|> pure (Special [])does not concatenate with the empty list, but rather with a list of aSpecialwrapping the empty list.