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 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', xa) <- a s
let (Rep f') = f xa
(s'', xf) <- f' s'
pure (s'', xf)
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 also have the following function:
readCharacter :: (Alternative f, Monad f) => Rep f Char
readCharacter = Rep $ \s -> case s of
[] -> empty
(x:xs) -> pure (xs,x)
The above function takes a state and returns empty if the state is an empty list. If the state is not an empty list, it returns a tuple with the first element the modified state and the second a Char, wrapped in the functor f.
And I also have the following function and data type:
data Res = Nil | Character Char | Cop Res Res | Special [Res]
findmatch :: (Monad f, Alternative f) => String -> Rep f Res
findmatch (cs) = do
x <- readCharacter
guard (x `elem` cs)
pure (Character x)
I am having trouble understanding how the above function works. It seems to me that for each character in the string cs, the readCharacter function is called. If the character returned by readCharacter is an element of the string cs, then the expression will evaluate to true. Suppose that the functor f is Maybe - then guard (True) will return a Just (), and then pure (Character x) is returned.
However, I am not sure what happens when the guard expression evaluates to False. For example, assuming that the functor is Maybe, guard False will return Nothing. If Nothing is returned by guard False, is it the case that the overall do block will return Nothing? Any insights are appreciated.
Related
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)
I have the following data types and function:
data TD = Empty | Fol TD TD | Letters [Char]
data Res = Nil | Character Char | Cop Res Res | Special [Res]
findmatch (Fol a b) = do
ra <- findmatch a
rb <- findmatch b
pure (Cop ra rb)
findmatch (Fol a b) = Cop <$> findmatch a <*> findmatch b
I am having trouble understanding how the second definition of findmatch involving the <$> works. I know that <$> has the following type declaration:
(<$>) :: (Functor f) => (a -> b) -> f a -> f b
f <$> x = fmap f x
The first argument to <$> should be a function, whilst the second should be a value wrapped in a functor. The result of findmatch is a value wrapped in a functor, however is Cop a function in this case? I know that Cop is a value constructor that takes two arguments of type Res. If one argument of type Res is passed to Cop, which is what I think occurs in Cop <$> findmatch a, this would return another function which takes a value of type Res. However, I am not sure what would be the type of the result that is returned by this second function that resulted from the partial application.
Any insights are appreciated.
However is Cop a function in this case? I know that Cop is a value constructor that takes two arguments of type Res.
Yes, Cop is a function with two parameters. It has the type Cop :: Res -> Res -> Res.
If one argument of type Res is passed to Cop, this would return another function which takes a value of type Res.
Yes. Cop <$> findmatch a :: Functor f => f (Res -> Res)
What would the type of the result that is returned by this second function that resulted from the partial application.
It's the type of the value that is constructed by the Cop constructor: it's constructing Res values.
I have the following data type:
newtype Rep f a = Rep { runRep :: String -> f (String, a) }
The above 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. f is a functor and the result of the computation is wrapped in the functor.
For the following function.
rep :: Functor f => Rep f a -> String -> f a
rep a s = fmap snd (runRep a s)
This function can be used to run a "Rep" computation on a string. However, I am not sure why runRep has to take a Rep f a as input as well as a String.
Further for the line fmap snd (runRep a s), I am not sure whether the second element of the tuple will be returned wrapped in the functor or without it.
Any insights are appreciated.
runRep is something you defined in your record:
newtype Rep f a = Rep { runRep :: String -> f (String, a) }
The compiler will automatically construct a "getter" function for that with the name runRep. Such getter has the signature:
someGetter :: Record -> TypeOfField
For your runRep, it is thus:
runRep :: Rep f a -> (String -> f (String, a))
or less verbose:
runRep :: Rep f a -> String -> f (String, a)
The runRep is thus a function that indeed takes a Rep f a, and returns a function that takes a String and returns an f (String, a).
I am not sure whether the second element of the tuple will be returned wrapped in the functor or without it.
You will perform an fmap snd on the f (String, a). fmap snd has as signature:
fmap snd :: Functor f => f (a, b) -> f b
So you can indeed state that it will return the second item of the data wrapped in the functor. Although "wrapped" might not be the best word here.
Note that if f ~ [], then you map on a list of 2-tuples, and you thus will return a list of all second items of that list.
Playing with Haskell and now I try to create a function like
keepValue :: (Monad m) => m a -> (a -> m b) -> m a
with following semantic: it should apply monad value to a function, which return the second monad, and keep the result of the first monad, but the effect of the second one
I have a working function in case of Maybe monad:
keepValueMaybe :: Maybe a -> (a -> Maybe b) -> Maybe a
keepValue ma f = case ma >>= f of
Nothing -> Nothing
Just _ -> ma
So if the first value is Nothing, the function is not run (so no second side-effect), but if the first value is Just, then, the function is run (with side effect). I keep effect of the second computation (e.g., Nothing makes the whole expression Nothing), but the original value.
Now I wonder. Can it work for any monad?
It looks kinda built-in >>, but I couldn't find anything in standard library.
Let's walk through this!
keepValue :: Monad m => m a -> (a -> m b) -> m a
keepValue ma f = _
So what do we want keepValue to do? Well, the first thing we should do is use ma, so we can connect it to f.
keepValue :: Monad m => m a -> (a -> m b) -> m a
keepValue ma f = do
a <- ma
_
Now we have a value va of type a, so we can pass it to f.
keepValue :: Monad m => m a -> (a -> m b) -> m a
keepValue ma f = do
va <- ma
vb <- f va
_
And finally, we want to produce va, so we can just do that:
keepValue :: Monad m => m a -> (a -> m b) -> m a
keepValue ma f = do
va <- ma
vb <- f va
return va
This is how I'd walk through writing the first draft of any monadic function like this. Then, I'd clean it up. First, some small things: since Applicative is a superclass of Monad, I prefer pure to return; we didn't use vb; and I'd drop the v in the names. So for a do-notation based version of this function, I think the best option is
keepValue :: Monad m => m a -> (a -> m b) -> m a
keepValue ma f = do
a <- ma
_ <- f a
pure a
Now, however, we can start to make the implementation better. First, we can replace _ <- f va with an explicit call to (>>):
keepValue :: Monad m => m a -> (a -> m b) -> m a
keepValue ma f = do
a <- ma
f a >> pure a
And now, we can apply a simplification. You may know that we can always replace (>>=) plus pure/return with fmap/(<$>): any of pure . f =<< ma, ma >>= pure . f, or do a <- ma ; pure $ f a (all of which are equivalent) can be replaced by f <$> ma. However, the Functor type class has another, less-well-known method, (<$):
(<$) :: a -> f b -> f a
Replace all locations in the input with the same value. The default definition is fmap . const, but this may be overridden with a more efficient version.
So we have a similar replacement rule for (<$): we can always replace ma >> pure b or do ma ; pure b with b <$ ma. This gives us
keepValue :: Monad m => m a -> (a -> m b) -> m a
keepValue ma f = do
a <- ma
a <$ f a
And I think this is the shortest reasonable version of this function! There aren't any nice point-free tricks to make this cleaner; one indicator of that is the multiple use of a on the second line of the do block.
Incidentally, a terminology note: you're running two monadic actions, or two monadic values; you're not running *"two monads". A monad is something like Maybe – a type constructor which supports (>>=) and return. Don't mix the values up with the types – this sort of terminological distinction helps keep things clearer!
This structure looks a lot like the definition of >>=/>> for Monad Maybe.
case foo of
Nothing -> Nothing
Just _ -> bar
foo >>= \_ -> bar
foo >> bar
so your original expression could be simplified to
ma >>= f >> ma
and this works for other monads.
However, I don't think this is actually what you want, as you can see ma occurring twice. Instead, take the value from the first ma >>= bind, and carry it through to the end of the computation.
keepValue ma f =
ma >>= \a ->
f a >>
return a
or in do-notation
keepValue ma f = do
a <- ma
f a
return a
You could define:
passThrough f = (>>) <$> f <*> pure
and then inplace of
keepValue ma f
write
ma >>= passThrough f
Then to read a line and print it twice (say) would be
getLine >>= passThrough putStrLn >>= putStrLn
I have trouble in understanding the following Applicative instance. Can someone explain me what Applicative do(in this case) and how it can be used? Or write it less obfuscated? Thanks!
newtype Parser a = P { getParser :: String -> Maybe (a, String) }
instance Applicative Parser where
pure = success
P p <*> P p' = P $ \s -> case p s of
Just (f, s') -> fmap (applyToFirst f) $ p' s'
Nothing -> Nothing
{-|
Applies a function to the first component of a pair.
-}
applyToFirst :: (a -> b) -> (a, c) -> (b, c)
applyToFirst f (x, y) = (f x, y)
Maybe the following equivalent code makes it more clear what's going on?
instance Applicative Parser where
pure v = P (\s -> Just (v, s))
P p <*> P p' = P $ \s -> case p s of
Just (f, s') -> case p' s' of
Just (v, s'') -> Just (f v, s'')
Nothing -> Nothing
Nothing -> Nothing
Combining two parsers with <*> gives you new parser. Given an input string, the new parser runs the first parser returning a result and the unparsed remainder of the string. The remainder of the string is given to the second parser returning a result and unparsed remainder. Then the two results are combined. If either parser fails the result is failure.
I'm trying to run this
newtype Test a = Test (Int, a)
instance Monad Test where
Test (_, []) >>= k =
k []
Test (_, a) >>= k =
k a
return a =
Test (0, a)
And I get the error:
Couldn't match expected type `a' with actual type `[t0]'
`a' is a rigid type variable bound by
the type signature for >>= :: Test a -> (a -> Test b) -> Test b
at C:\Users\david.phillips\Documents\code\test.hs:4:5
In the pattern: []
In the pattern: (_, [])
In the pattern: Test (_, [])
I get a similar error when I tried using a case statement instead of 2 versions of >>=.
I'm fairly new to haskell and can't see why this wouldn't work.
Edit: Sorry, it's a bad example. Suppose that the first definition of >>= gave a different output.
class Monad m where
(>>=) :: m a -> (a -> m b) -> m b
(>>) :: m a -> m b -> m b
return :: a -> m a
fail :: String -> m a
Monad instances are parameterized over a type variable a. You are essentially claiming that it is not, because in the place of that variable, you have pattern matched on the empty list constructor, [], meaning "a is a list of something." The type of eg. bind could, with explicit quantification, be written:
(>>=) :: forall a. m a -> (a -> m b) -> m b
Your definition cannot possibly hold for ALL a.
As an addition to Sarah's answer, you can actually omit your specific pattern match,
Test (_, []) >>= f = f []
is the same as
Test (_, a) >>= f = f a
So you can really just write this as
Test (_, a) >>= f = f a
return a = (0, a)
Now remember that in addition to have the right types, we're supposed to have that
m >>= return = m
return a >>= f = f a
(a >>= b) >>= c = a >>= (\a' -> b a' >>= c)
This worries me though, as
m = Test (1, 'c')
m >>= return === return 'c' === (0, 'c') /== m
So return is no longer functioning as an identity and you're breaking the 1st monad law. Fixing this would mean return would have to preserve the first element of the tuple, problematic since we don't actually tell it about it.
Naively, let's just clobber the first tuple element that our function returns.
Test (a, b) >>= f = Test (a, snd (f b))
Now
Test (1, 'c') >>= return == Test (1, snd (return 'c')) == Test (1, 'c')
But we're still in trouble,
let f a = Test (1, a)
return a >>= f == Test (0, snd (f a)) == Test (0, a) /== f a
So the trick here is to do what the state monad does
newtype Test a = Test{ unTest :: Int -> (Int, a) }
instance Monad Test where
return a = Test $ \i -> (i, a)
(Test m) >>= f = Test $ \i -> let (i', a) = m i
in unTest (f a) $ i'
Which does satisfy the monad laws*. Happily this already exists in Control.Monad.State.
** modulo seq
Get rid of the first pattern. You are trying to make a separate definition for a specific type, which you can't do. All of the definitions need to be for all types a. If you could violate that, the first pattern would be the same as the second pattern but with a bound to [], so just write:
instance Monad Test where
Test (_, a) >>= k =
k a
return a =
Test (0, a)
Test (0, []) >>= k would then match the >>= pattern, and become k [], exactly the same as what your first pattern is unnecessarily trying to do.