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.
Related
I am doing an Haskell tutorial about Applicative Functor :
CIS194: Homework10 - applicative
In the tutorial, the below parser is given:
-- A parser for a value of type a is a function which takes a String
-- representing the input to be parsed, and succeeds or fails; if it
-- succeeds, it returns the parsed value along with the remainder of
-- the input.
newtype Parser a = Parser { runParser :: String -> Maybe (a, String) }
On exercise 2, we are asked to implement an Applicative instance for Parser.
Before implementing Applicative, we need to implement Functor.
My Functor Parser implementation is :
instance Functor Parser where
fmap f p = Parser ( -- take a function and a parser
\s0 -> case runParser p s0 of -- parse a string
Nothing -> Nothing -- if parse fails, returns nothing
Just (a,s1) -> Just (f a,s1) -- if parse succeed, returns
--1. 1st function applied to parsed result
--2. remaining string
)
However i found anoter way to implement this Functor :
bschwb /cis194-solutions
The Functor Parser implementation is :
first :: (a -> b) -> (a, c) -> (b, c)
first f (a, c) = (f a, c)
instance Functor Parser where
fmap f (Parser rp) = Parser (fmap (first f) . rp)
I do not understand the '. rp' part, can you please help me ?
To my understanding :
Parser rp : 'rp' can be anything (Integer, tuple, function ...) and we are not supposed to know what it is;
The '.' operator applies only to functions;
So we can not mix '.' and 'rp' because we are not sure 'rp' will be a function.
What did I miss or misunderstand ?
Thank you for your help.
In newtype Parser a = Parser { runParser :: String -> Maybe (a, String) }, I was focusing on the data type Parser a, and not on the constructor Parser :: (String -> Maybe (a, String)) -> Parser a.
Now this is clear:
instance Functor Parser where
fmap -- Functor f => (a->b) -> f a -> f b
func -- a -> b
(Parser rp) -- regarding Parser constructor rp :: String -> Maybe (a, String)
= Parser
(
fmap (first func) -- we can deduce : fmap (first func) :: Functor f => f (a, c) -> f (func a, c)
. -- and we know : (.) :: (b -> c) -> (a -> b) -> (a -> c)
rp -- rp :: String -> Maybe (a, String)
) -- therefore : fmap (first func).rp :: String -> Maybe (func a, String)
Thanks duplode for his comment.
I'm trying to understand some code and I'm getting myself tangled fairly well. Please help me to understand my logic, or lack thereof ...
To start:
*Main> :t fmap
fmap :: Functor f => (a -> b) -> f a -> f b
If I just want f a to be a function that takes one parameter, it's okay and makes sense:
*Main> :t \f -> fmap f (undefined :: String -> Int)
\f -> fmap f (undefined :: String -> Int) :: (Int -> b) -> String -> b
I can pass in a String in the second param, which generates an Int, and then use the function in the first param to generate the b.
Now, I want f a to be a function that takes two parameters, so I substitute that in:
*Main> :t \f -> fmap f (undefined :: String -> Int -> Bool)
\f -> fmap f (undefined :: String -> Int -> Bool)
:: ((Int -> Bool) -> b) -> String -> b
At this point, I'm confused. I already provided the function that converts from the String and the Int into the Bool. How can I now provide another function that takes a Int -> Bool to convert into a b? Is this non-sensical or am I not reading this right?
Or maybe this is a case of a functor within a functor and more needs to be done to make this make sense? In which case, what?
There is actually no such thing as a function with two parameters in Haskell. Every function has exactly one parameter.
In particular, String -> Int -> Bool is a function which accepts one String parameter. (Of course, knowing that the result is again a function you are able to use it as if it were a function with two parameters.) So if you want to unify this with f a, you need
f ~ (String->)
a ~ Int->Bool
Indeed Int->Bool can itself be interpreted as a functor-application†
f ~ (String->)
g ~ (Int->)
b ~ Bool
so that String->Int->Bool ~ f (g b); thus
\f -> fmap (fmap f) (undefined :: String -> Int -> Bool)
:: (Bool -> b) -> String -> Int -> b
I don't think the function family of functors is really a good example for grasping properties of functors/applicatives/monads. List and maybes are generally much less confusing; instead of the plain function functor the equivalent Reader is preferred when you need that functionality (pun not intended).
Regarding your original expression, that is actually not meaningless. If we translate it to a tamer functor, we could for instance write
> fmap ($2) [(>1), (>2), (>3)]
[True, False, False]
Much the same thing can be done with the function functor:
> fmap ($2) (<) 1
True
> fmap ($2) (<) 2
False
> fmap ($2) (<) 3
False
Of course that example is a bit too simple to be useful, but you can also implement nontrivial ones.
†Note that f and g are actually not the same functor. We tend to call them both “the function functor”, but really you get a different functor for every partial application of the (->) constructor. That means, you can't in any way unify the two layers, even though there's a Monad (a->) instance.
New to Haskell, and am trying to figure out this Monad thing. The monadic bind operator -- >>= -- has a very peculiar type signature:
(>>=) :: Monad m => m a -> (a -> m b) -> m b
To simplify, let's substitute Maybe for m:
(>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
However, note that the definition could have been written in three different ways:
(>>=) :: Maybe a -> (Maybe a -> Maybe b) -> Maybe b
(>>=) :: Maybe a -> ( a -> Maybe b) -> Maybe b
(>>=) :: Maybe a -> ( a -> b) -> Maybe b
Of the three the one in the centre is the most asymmetric. However, I understand that the first one is kinda meaningless if we want to avoid (what LYAH calls boilerplate code). However, of the next two, I would prefer the last one. For Maybe, this would look like:
When this is defined as:
(>>=) :: Maybe a -> (a -> b) -> Maybe b
instance Monad Maybe where
Nothing >>= f = Nothing
(Just x) >>= f = return $ f x
Here, a -> b is an ordinary function. Also, I don't immediately see anything unsafe, because Nothing catches the exception before the function application, so the a -> b function will not be called unless a Just a is obtained.
So maybe there is something that isn't apparent to me which has caused the (>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b definition to be preferred over the much simpler (>>=) :: Maybe a -> (a -> b) -> Maybe b definition? Is there some inherent problem associated with the (what I think is a) simpler definition?
It's much more symmetric if you think in terms the following derived function (from Control.Monad):
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> (a -> m c)
(f >=> g) x = f x >>= g
The reason this function is significant is that it obeys three useful equations:
-- Associativity
(f >=> g) >=> h = f >=> (g >=> h)
-- Left identity
return >=> f = f
-- Right identity
f >=> return = f
These are category laws and if you translate them to use (>>=) instead of (>=>), you get the three monad laws:
(m >>= g) >>= h = m >>= \x -> (g x >>= h)
return x >>= f = f x
m >>= return = m
So it's really not (>>=) that is the elegant operator but rather (>=>) is the symmetric operator you are looking for. However, the reason we usually think in terms of (>>=) is because that is what do notation desugars to.
Let us consider one of the common uses of the Maybe monad: handling errors. Say I wanted to divide two numbers safely. I could write this function:
safeDiv :: Int -> Int -> Maybe Int
safeDiv _ 0 = Nothing
safeDiv n d = n `div` d
Then with the standard Maybe monad, I could do something like this:
foo :: Int -> Int -> Maybe Int
foo a b = do
c <- safeDiv 1000 b
d <- safeDiv a c -- These last two lines could be combined.
return d -- I am not doing so for clarity.
Note that at each step, safeDiv can fail, but at both steps, safeDiv takes Ints, not Maybe Ints. If >>= had this signature:
(>>=) :: Maybe a -> (a -> b) -> Maybe b
You could compose functions together, then give it either a Nothing or a Just, and either it would unwrap the Just, go through the whole pipeline, and re-wrap it in Just, or it would just pass the Nothing through essentially untouched. That might be useful, but it's not a monad. For it to be of any use, we have to be able to fail in the middle, and that's what this signature gives us:
(>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
By the way, something with the signature you devised does exist:
flip fmap :: Maybe a -> (a -> b) -> Maybe b
The more complicated function with a -> Maybe b is the more generic and more useful one and can be used to implement the simple one. That doesn't work the other way around.
You can build a a -> Maybe b function from a function f :: a -> b:
f' :: a -> Maybe b
f' x = Just (f x)
Or, in terms of return (which is Just for Maybe):
f' = return . f
The other way around is not necessarily possible. If you have a function g :: a -> Maybe b and want to use it with the "simple" bind, you would have to convert it into a function a -> b first. But this doesn't usually work, because g might return Nothing where the a -> b function needs to return a b value.
So generally the "simple" bind can be implemented in terms of the "complicated" one, but not the other way around. Additionally, the complicated bind is often useful and not having it would make many things impossible. So by using the more generic bind monads are applicable to more situations.
The problem with the alternative type signature for (>>=) is that it only accidently works for the Maybe monad, if you try it out with another monad (i.e. List monad) you'll see it breaks down at the type of b for the general case. The signature you provided doesn't describe a monadic bind and the monad laws can't don't hold with that definition.
import Prelude hiding (Monad, return)
-- assume monad was defined like this
class Monad m where
(>>=) :: m a -> (a -> b) -> m b
return :: a -> m a
instance Monad Maybe where
Nothing >>= f = Nothing
(Just x) >>= f = return $ f x
instance Monad [] where
m >>= f = concat (map f m)
return x = [x]
Fails with the type error:
Couldn't match type `b' with `[b]'
`b' is a rigid type variable bound by
the type signature for >>= :: [a] -> (a -> b) -> [b]
at monadfail.hs:12:3
Expected type: a -> [b]
Actual type: a -> b
In the first argument of `map', namely `f'
In the first argument of `concat', namely `(map f m)'
In the expression: concat (map f m)
The thing that makes a monad a monad is how 'join' works. Recall that join has the type:
join :: m (m a) -> m a
What 'join' does is "interpret" a monad action that returns a monad action in terms of a monad action. So, you can think of it peeling away a layer of the monad (or better yet, pulling the stuff in the inner layer out into the outer layer). This means that the 'm''s form a "stack", in the sense of a "call stack". Each 'm' represents a context, and 'join' lets us join contexts together, in order.
So, what does this have to do with bind? Recall:
(>>=) :: m a -> (a -> m b) -> m b
And now consider that for f :: a -> m b, and ma :: m a:
fmap f ma :: m (m b)
That is, the result of applying f directly to the a in ma is an (m (m b)). We can apply join to this, to get an m b. In short,
ma >>= f = join (fmap f ma)
type PT_Int = Int
type PT_String = String
data PolyType = PT_Int Int | PT_String String
Given a function f, how do I write a function that lifts it into PolyType?
(just trying to understand lifting)
Your PolyType is equivalent to Either Int String. In case you haven't seen Either before:
data Either a b = Left a | Right b
so you could have a function like
liftP :: (Either Int String -> a) -> PolyType -> a
liftP f poly = case poly of
PT_Int i -> f (Left i)
PT_String s -> f (Right s)
PolyType contains either Int or String, so you can only lift functions that are defined over both Int and String.
That said, I don't think this is what you're after. The term "lifting" is usually used in the context of polymorphic data types like [a], Maybe a, (->) a or in general some type f a where f :: * -> *.
In these cases, given a function g :: a -> b, you want a new function [a] -> [b], Maybe a -> Maybe b or in general f a -> f b. This is exactly fmap from Functor.
class Functor f where
fmap :: (a -> b) -> (f a -> f b)
but your PolyType is monomorphic (it doesn't have a free variable in its type. To be precise, it has kind *) so it can't be a Functor.
You chould change your definition of PolyType to
data PolyType a = PT a
Now this is a valid Functor (it's just the Identity Functor)
instance Functor PolyType where
fmap f (PT a) = PT (f a)
The type of fmap (specialized for this particular PolyType instance) is
fmap :: (a -> b) -> PolyType a -> PolyType b
According to the Typeclassopedia and this link a type can only have a single Functor instance (there's a proof in the link). But it is my understanding that it is possible for a given type to have multiple possible Monad instances, is this right? But for a given Monad instance there is a free Functor instance with
fmap f xs = xs >>= return . f
From this, I conclude that if I stumble upon a type in which I can define multiple Monad instances in different ways, then the fmap function derived as above must equal for all of them, in other words, if I have two pairs of functions:
bind_1 :: m a -> (a -> m b) -> m b
unit_1 :: a -> m a
bind_2 :: m a -> (a -> m b) -> m b
unit_2 :: a -> m a
for the same type constructor m, than, necessarily:
xs `bind_1` (unit_1 . f) == xs `bind_2` (unit_2 . f)
for all xs :: a and f :: a -> b.
Is this true? Does this hold as a theorem?
Yes. In fact we can make the stronger statement that all function with the type
fmap :: (a -> b) -> (F a -> F b)
such that fmap id = id are equivalent. This actually just falls out of the type of fmap with something called parametricity.
In your case, if >>= and return satisfy the monad laws, then
mFmap f a = a >>= return . f
mFmap id a = a >>= return . id
mFmap id a = a >>= return
mFmap id a = a
mFmap id = id
By the monad law that a >>= return is just a. Using this result, we can appeal to the free theorem we get from parametricity and we have our proof.