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.
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 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.
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.
When learning the Reader Monad, I find that it is defined as:
newtype Reader r a = Reader { runReader :: r -> a }
instance Monad (Reader r) where
return a = Reader $ \_ -> a
m >>= k = Reader $ \r -> runReader (k (runReader m r)) r
I want to known why using function as constructor parameter instead of something else such as a tuple:
newtype Reader r a = Reader { runReader :: (r, a) }
instance Monad (Reader r) where
-- Here I cannot get r when defining return function,
-- so does that's the reason that must using a function whose input is an "r"?
return a = Reader (r_unknown, a)
m >>= k = Reader (fst $ runReader m) (f (snd $ runReader m))
According to the Reader definition, we need a "environment" which we can use to generate a "value". I think a Reader type should contain the information of "environment" and "value", so the tuple seems perfect.
You didn't mention it in the question, but I guess you thought specifically of using a pair for defining Reader because it also makes sense to think of that as a way of providing a fixed environment. Let's say we have an earlier result in the Reader monad:
return 2 :: Reader Integer Integer
We can use this result to do further calculations with the fixed environment (and the Monad methods guarantee it remains fixed throughout the chain of (>>=)):
GHCi> runReader (return 2 >>= \x -> Reader (\r -> x + r)) 3
5
(If you substitute the definitions of return, (>>=) and runReader in the expression above and simplify it, you will see exactly how it reduces to 2 + 3.)
Now, let's follow your suggestion and define:
newtype Env r a = Env { runEnv :: (r, a) }
If we have an environment of type r and a previous result of type a, we can make an Env r a out of them...
Env (3, 2) :: Env Integer Integer
... and we can also get a new result from that:
GHCi> (\(r, x) -> x + r) . runEnv $ Env (3, 2)
5
The question, then, is whether we can capture this pattern through the Monad interface. The answer is no. While there is a Monad instance for pairs, it does something quite different:
newtype Writer r a = Writer { Writer :: (r, a) }
instance Monoid r => Monad (Writer r) where
return x = (mempty, x)
m >>= f = Writer
. (\(r, x) -> (\(s, y) -> (mappend r s, y)) $ f x)
$ runWriter m
The Monoid constraint is needed so that we can use mempty (which solves the problem that you noticed of having to create a r_unknown out of nowhere) and mappend (which makes it possible to combine the first elements of the pair in a way that doesn't violate the monad laws). This Monad instance, however, does something very different than what the Reader one does. The first element of the pair isn't fixed (it is subject to change, as we mappend other generated values to it) and we don't use it to compute the second element of the pair (in the definition above, y does not depend neither on r nor on s). Writer is a logger; the r values here are output, not input.
There is one way, however, in which your intuition is justified: we can't make a reader-like monad using a pair, but we can make a reader-like comonad. To put it very loosely, Comonad is what you get when you turn the Monad interface upside down:
-- This is slightly different than what you'll find in Control.Comonad,
-- but it boils down to the same thing.
class Comonad w where
extract :: w a -> a -- compare with return
(=>>) :: w a -> (w a -> b) -> w b -- compare with (>>=)
We can give the Env we had abandoned a Comonad instance:
newtype Env r a = Env { runEnv :: (r, a) }
instance Comonad (Env r) where
extract (Env (_, x)) = x
w#(Env (r, _)) =>> f = Env (r, f w)
That allows us to write the 2 + 3 example from the beginning in terms of (=>>):
GHCi> runEnv $ Env (3, 2) =>> ((\(r, x) -> x + r) . runEnv)
(3,5)
One way to see why this works is noting that an a -> Reader r b function (i.e. what you give to Reader's (>>=)) is essentially the same thing that an Env r a -> b one (i.e. what you give to Env's (=>>)):
a -> Reader r b
a -> (r -> b) -- Unwrap the Reader result
r -> (a -> b) -- Flip the function
(r, a) -> b -- Uncurry the function
Env r a -> b -- Wrap the argument pair
As further evidence of that, here is a function that changes one into the other:
GHCi> :t \f -> \w -> (\(r, x) -> runReader (f x) r) $ runEnv w
\f -> \w -> (\(r, x) -> runReader (f x) r) $ runEnv w
:: (t -> Reader r a) -> Env r t -> a
GHCi> -- Or, equivalently:
GHCi> :t \f -> uncurry (flip (runReader . f)) . runEnv
\f -> uncurry (flip (runReader . f)) . runEnv
:: (a -> Reader r c) -> Env r a -> c
To wrap things up, here is a slightly longer example, with Reader and Env versions side-by-side:
GHCi> :{
GHCi| flip runReader 3 $
GHCi| return 2 >>= \x ->
GHCi| Reader (\r -> x ^ r) >>= \y ->
GHCi| Reader (\r -> y - r)
GHCi| :}
5
GHCi> :{
GHCi| extract $
GHCi| Env (3, 2) =>> (\w ->
GHCi| (\(r, x) -> x ^ r) $ runEnv w) =>> (\z ->
GHCi| (\(r, x) -> x - r) $ runEnv z)
GHCi| :}
5
First of all note that your bind function is wrong and would not compile.
If the Reader were defined as you describe with a tuple, there would be problems:
The monad laws would be violated, e.g. left identity, which states that:
return a >>= f == f a
or the right identity:
m >>= return == m
would be broken, depending on the implmentation of >>= because >>= would forget either the first tuple element of the first argument or the second, i.e. if the implmentation would be:
(Reader (mr, mv)) >>= f =
let (Reader (fr, fv)) = f mv
in Reader (mr, fv)
then we would always lose the reader value that comes out of f (aka fr) and otherwise if >>= would be
(Reader (mr, mv)) >>= f =
let (Reader (fr, fv)) = f mv
in Reader (fr, fv)
-- ^^^ tiny difference here ;)
we would always lose mr.
A Reader is some action, that may ask for a constant value, which cannot be changed by another monadic action, which is read-only.
But when defined with a tuple, we could super-easy overwrite the reader value, e.g. whith this function:
tell :: x -> BadReader x ()
tell x = BadReader (x, ())
If a reader is instead defined with a function, this is impossible (try it)
Also, that enviroment is actually not required before converting a Reader to a pure value (aka running the Reader), so from this alone it makes sense to use a function instead of a tuple.
When using a tuple, we would have to provide the Reader value even before we actually run an action.
You can see that in your return definition, you even point out the problem, where the r_unknown comes from ...
To get a btter intuition, let's assume a Reader action that returns the Persons with a certain age from the Addressbook:
data Person = MkPerson {name :: String, age :: Int}
type Addressbook = [Person]
personsWithThisAge :: Int -> Reader Addressbook [Person]
personsWithThisAge a = do
addressbook <- ask
return (filter (\p -> age p == a) addressbook)
This personsWithAge function returns a Reader action and since it only asks for the Addressbook, it is like a function that accepts an addressbook and gives back a [Person] list,
so it is natural to define a reader as just that, a function from some input to a result.
We could rewrite this Reader action to be a function of the Addressbook like this:
personsWithThisAgeFun :: Int -> Addressbook -> [Person]
personsWithThisAgeFun a addressbook =
filter (\p -> age p == a) addressbook
But why invent Reader??
The real value of Reader shows when combining several functions like e.g. personsWithThisAge, that all depend on (the same) one constant Addressbook.
Using a Reader we don't have to explicitly pass some Addressbook around, individual Reader actions don't even have any way at all to modify the Addressbook - Reader guarantees us, that every action uses the same, unmodified Addressbook, and all a Reader action can ever to with the environment is ask for it.
The only way to implement this, with these guarantees is with a function.
Also if you look at the monad instances that are included in the standard library, you will see that (r ->) is a monad; actually it is identical to the Reader monad apart from some technical differences.
Now the structure you describe with the tuple is actually pretty close to a Writer monad, what is write-only , but that's out of scope.
I would like to create my own monad in Haskell, and have Haskell treat it just like any other built in monad. For instance, here is code for creating a monad that updates some global state variable each time it is called, along with an evaluator that uses it to compute the number of times the quot function is called:
-- define the monad type
type M a = State -> (a, State)
type State = Int
-- define the return and bind operators for this monad
return a x = (a, x)
(>>=) :: M a -> (a -> M b) -> M b
m >>= k = \x -> let (a,y) = m x in
let (b,z) = k a y in
(b,z)
-- define the tick monad, which increments the state by one
tick :: M ()
tick x = ((), x+1)
data Term = Con Int | Div Term Term
-- define the evaluator that computes the number of times 'quot' is called as a side effect
eval :: Term -> M Int
eval (Con a) = Main.return a
eval (Div t u) = eval t Main.>>= \a -> eval u Main.>>= \b -> (tick Main.>>= \()->Main.return(quot a b))
answer :: Term
answer = (Div (Div (Con 1972)(Con 2))(Con 23))
(result, state) = eval answer 0
main = putStrLn ((show result) ++ ", " ++ (show state))
As implemented now, return and >>= belong in the namespace Main, and I have to distinguish them from Prelude.return and Prelude.>>=. If I wanted Haskell to treat M like any other type of monad, and properly overload the monad operators in Prelude, how would I go about that?
To make your new monad work with all the existing Haskell machinery--do notation, for instance--all you need to do is declare your type an instance of the Monad typeclass. Then the Prelude functions >>=, return, etc. will work with your new type just as they do with all other Monad types.
There's a limitation, though, that will require some changes in your examples. Type synonyms (declared with type) cannot be made class instances. (Your M a is exactly the same as Int -> (a, Int).) You'll need to use data or newtype instead. (The distinction between those two is not relevant here.)
Both of those keywords create a genuinely new type; in particular, they create a new data constructor. You should read up on this in any fundamental Haskell text. Briefly, newtype X a = Y (...) creates a new type X a; you can create values of that type using the constructor Y (which can, and often does, have the same name as the type constructor X); and you can consume values by pattern matching on Y. If you choose not to export the data constructor Y, only functions in your module will be able to manipulate the values directly.
(There's a GHC extension TypeSynonymInstances but it won't help you here, because of a separate issue: type synonyms cannot be partially applied; for any type X a = {- ... -} you can only write X a or X Int or whatnot, never just X. You can't write instance Monad M because M is partially applied.)
After that, all you need to do is move your definitions of return and >>= into an instance Monad declaration:
newtype M a = M (State -> (a, State))
instance Monad M where
return a = M $ \x -> (a, x)
m >>= k = {- ... -}
Note that the implementation of (>>=) is slightly verbose because you need to unwrap and rewrap the newtype using its data constructor M. Look at the implementation of StateT in transformers, which uses a record accessor to make it easier. (You can manually write a function runM :: M -> State -> (a, State) equivalent to the record syntax that transformers and many other packages use.)
Here is an implementation:
-- Otherwise you can't do the Applicative instance.
import Control.Applicative
-- Simple function
foo :: String -> String
foo x = do
x ++ "!!!"
-- Helper for printing Monads
print2 :: (Show a) => MyBox a -> IO()
print2 (MyBox x) = print x
-- Custom type declaration
data MyBox a = MyBox a
-- MyBox functor
instance Functor MyBox where
fmap f (MyBox x) = MyBox (f x)
-- MyBox Applicative
instance Applicative MyBox where
pure = MyBox
(MyBox f) <*> x = f <$> x
-- MyBox Monad
instance Monad MyBox where
return x = MyBox x
MyBox x >>= f = f x
-- (MyBox as a functor) Use a function with a wrapped value
result1 = foo <$> (MyBox "Brian")
-- (MyBox as an Applicative) Use a wrapped function with a wrapped value
result2 = (MyBox foo) <*> (MyBox "Erich")
-- (MyBox as a Monad) Use a wrapped value with a lambda (it can be chainable)
myLambda1 = (\ x -> MyBox (x ++ " aaa"))
myLambda2 = (\ x -> MyBox (x ++ " bbb"))
myLambda3 = (\ x -> MyBox (x ++ " ccc"))
result3 = (MyBox "Rick")
>>= myLambda1
>>= myLambda2
>>= myLambda3
-- Another Monad syntax
result4 = do
x <- MyBox "A"
y <- MyBox "B"
z <- MyBox "C"
MyBox (x ++ y ++ z)
main = do
print2(result1) -- "Brian!!!"
print2(result2) -- "Erich!!!"
print2(result3) -- "Rick aaa bbb ccc"
print2(result4) -- "ABC"
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.