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.
Related
I am learning haskell currently and I am having a really hard time wrapping my head around how to explain <$> and <*>'s behavior.
For some context this all came from searching how to use an or operation when using takeWhile and the answer I found was this
takeWhile ((||) <$> isDigit <*> (=='.'))
In most of the documentation I have seen, <*> is used with a container type.
show <*> Maybe 10
By looking at
(<$>) :: Functor f => (a -> b) -> f a -> f b
It tells me that <*> keeps the outer container if its contents and applies the right to the inside, then wraps it back into the container
a b f a f b
([Int] -> String) -> [Just]([Int]) -> [Just]([String])
This makes sense to me, in my mind the f a is essentially happening inside the container, but when I try the same logic, I can make sense to me but I cant correlate the logic
f = (+) <$> (read)
so for f it becomes
a b f a f b
([Int] -> [Int -> Int]) -> ([String] -> [Int]) -> ([String] -> [Int -> Int])
So f being the container really confuses me when I try and work out what this code is going to do. I understand when I write it out like this, I can work it out and see its basically equivalent to the .
(.) :: (b -> c) -> (a -> b) -> a -> c
b c a b a c
([Int] -> [Int -> Int]) -> ([String] -> [Int]) -> ([String] -> [Int -> Int])
so it can be written as
f = (+) . read
Why not just write it as just that? Why wasn't the original snippet just written as
takeWhile ((||) . isDigit <*> (=='.'))
or does <$> imply something in this context that . des not?
Now looking at <*>, it seems like it is basicly exactly the same as the <$> except it takes two containers, uses the inner of both, then puts it pack in the container
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
so
Just show <*> Just 10
f a b f a f b
[Just]([Int->Int]->[Int]) -> [Just]([Int->Int]) -> [Just]([Int])
However with functions, it becomes murky how things are being passed around to each other.
Looking at the original snippit and breaking it up
f1 :: Char -> Bool -> Bool
f1 = (||) . isDigit
f2 :: Char -> Bool
f2 = f1 <*> (== '.')
<*> behavior in f2 is
f a b f a f b
([Char] -> [Bool] -> [Bool]) -> ([Char] -> [Bool]) -> ([Char] -> [Bool])
So using previous logic, I see it as Char -> is the container, but its not very useful for me when working out what's happening.
It looks to me as if <*> is passing the function parameter into right side, then passing the same function parameter, and the return value into the left?
So to me, it looks equivalent to
f2 :: Char -> Bool
f2 x = f1 x (x=='_')
Its a bit of mental gymnastics for me to work out where the data is flowing when I see <*> and <$>. I guess im just looking for how an experienced haskell-er would read these operations in their head.
The applicative instance for functions is quite simple:
f <*> g = \x -> f x (g x)
You can verify for yourself that the types match up. And as you said,
(<$>) = (.)
(Ignoring fixity)
So you can rewrite your function:
(||) <$> isDigit <*> (=='.')
(||) . isDigit <*> (=='.')
\x -> ((||) . isDigit) x ((=='.') x)
-- Which can simply be rewritten as:
\x -> isDigit x || x == '.'
But it's important to understand why the function instance is as it is and how it works. Let's begin with Maybe:
instance Applicative Maybe where
pure :: a -> Maybe a
pure x = Just x
(<*>) :: Maybe (a -> b) -> Maybe a -> Maybe b
Nothing <*> _ = Nothing
_ <*> Nothing = Nothing
(Just f) <*> (Just x) = Just (f x)
Ignore the implementation here and just look at the types. First, notice that we've made Maybe an instance of Applicative. What exactly is Maybe? You might say that it's a type, but that isn't true - I can't write something like
x :: Maybe
- that doesn't make sense. Instead, I need to write
x :: Maybe Int
-- Or
x :: Maybe Char
or any other type after Maybe. So we give Maybe a type like Int or Char, and it suddenly becomes a type itself! That's why Maybe is what's known as a type constructor.
And that's exactly what the Applicative typeclass expects - a type constructor, which you can put any other type inside. So, using your analogy, we can think of giving Applicative a container type.
Now, what do I mean by
a -> b
?
We can rewrite it using prefix notation (the same way 1 + 2 = (+) 1 2)
(->) a b
And here we see that the arrow (->) itself is also just a type constructor - but unlike Maybe, it takes two types. But Applicative only wants a type constructor which takes one type. So we give it this:
instance Applicative ((->) r)
Which means that for any r, (->) r is an Applicative. Continuing the container analogy, (->) r is now a container for any type b such that the resulting type is r -> b. What that means is that the contained type is actually the future result of the function on giving it an r.
Now for the actual instance:
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
Substituting (->) r as the applicative,
(<*>) :: ((->) r (a -> b)) -> ((->) r a) ((->) r b)
-- Rewriting it in infix notation:
(<*>) :: (r -> (a -> b)) -> (r -> a) -> (r -> b)
How would we go about writing the instance? Well, we need a way to get the contained type out of the container - but we can't use pattern matching like we did with Maybe. So, we use a lambda:
(f :: r -> (a -> b)) <*> (g :: r -> a) = \(x :: r) -> f x (g x)
And the type of f x (g x) is b, so the entire lambda has type r -> b, which is exactly what we were looking for!
EDIT: I noticed that I didn't talk about the implementation of pure for functions - I could update the answer, but try seeing if you can use the type signature to work it out yourself!
I am trying to implement my own functor instances and quickcheck them, and have run into issues on typeclasses which are not instances of Eq, namely (->) and IO. My attempts result in a No instance for (Eq ...) error.
In the (->) case I had run into a similar error with Show, i.e. No instance for (Show ...), and was able to fix that by adding a Show (a -> b) instance as suggested in an answer here. It would seem that I might be able to solve also the lack of Eq instances by adding them similarly. However, this question on function equality notes that that in Haskell creating an instance of Eq (a -> b) is equivalent to the halting problem and therefore impossible.
I'm not sure whether creating an instance of Eq IO a is possible. In the IO case I also run into a No instance for (Arbitrary ...) error.
Is there some way to quickcheck the functor properties of the function type (->)? Is there some way to do the same for the IO type?
My code is as follows.
import Prelude hiding (Functor, fmap)
import Test.QuickCheck
import Test.QuickCheck.Function
class Functor f where
fmap :: (a -> b) -> f a -> f b
instance Functor IO where
fmap h f = f >>= (pure . h)
instance Functor ((->) e) where
fmap = (.)
data T a = T
prop_functorid :: (Functor f, Eq (f a)) => T (f a) -> f a -> Bool
prop_functorid T x = fmap id x == x
prop_functorcompose :: (Functor f, Eq (f c)) => T (f a) -> T b -> T c -> f a -> Fun a b -> Fun b c -> Bool
prop_functorcompose T T T x (apply -> g) (apply -> h) =
fmap (h . g) x == (fmap h . fmap g) x
instance Show (a -> b) where
show a= "function"
prop_function :: IO ()
prop_function = do
quickCheck $ prop_functorid (T :: T (String -> String))
quickCheck $ prop_functorcompose (T :: T (String -> String)) (T :: T String) (T :: T String)
prop_io :: IO ()
prop_io = do
quickCheck $ prop_functorid (T :: T (IO String))
quickCheck $ prop_functorcompose (T :: T (IO String)) (T :: T String) (T :: T String)
main = do
prop_function
prop_io
Haskell newbie here.
So (<$>) is defined as
(<$>) :: Functor f => (a -> b) -> f a -> f b
And (<*>) is defined as
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
But I feel like Applicative is two concepts in one:
One would be that of a functor
And one would be this:
(<#>) :: MyConcept m => m (a -> b) -> a -> b
So e.g. thinking in terms of Maybe:
I have an let i = 4 and I have a let foo = Nothing :: Num a => Maybe (a -> a).
Basically I have a function that may or may not be there, that takes an Int and returns an Int, and an actual Int.
Of course I could just wrap i by saying:
foo <*> Just i
But that requires me to know the what Applicative foo is wrapped in.
Is there something equivalent to what I described here? How would I go about implementing that function <#> myself?
It would be something like this:
let (<#>) func i = func <*> ??? i
You can use pure:
pure :: Applicative f => a -> f a
foo <*> pure i
although you could just use fmap:
fmap (\f -> f i) foo
or
fmap ($ i) foo
(<#>) :: MyConcept m => m (a -> b) -> a -> b
To see if this is like an Applicative try deriving <#> from <*> and pure. You will find that it is impossible.
Where you can find <#> in a more general form is extract :: (Counit w) => w a -> a for comonads.
Can you implement extract for Maybe? What do you do when the value is Nothing?
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.
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