I'm trying to understand the explaination in Monads made difficult and I have a hard time figuring out the following newtype definition:
newtype (FComp g f) x = FComp { unCompose :: g (f x) }
instance (Functor b c f, Functor a b g) => Functor a c (FComp g f) where
fmap f (FComp xs) = FComp $ fmap (fmap f) xs
I have nowhere seen an explaination of what newtype means with an expression in parentheses in place of the type declaration. I therefore cannot figure out what the definition of the fmap function means. I also don't understand why the unCompose field accessor is defined but never used. I feel like I am missing some basic semantics of newtype.
A little test:
newtype (FComp g f) x = FComp { unCompose :: g (f x) }
newtype FComp2 g f x = FComp2 { unCompose2 :: g (f x) }
*Main> :i FComp
newtype FComp g f x = FComp {unCompose :: g (f x)}
-- Defined at Test.hs:34:10
*Main> :i FComp2
newtype FComp2 g f x = FComp2 {unCompose2 :: g (f x)}
-- Defined at Test.hs:35:9
So the parentheses really don't change anything. It's just the same as without them.
As for the uncompose, it's just a name to unwrap the newtype without making the data constructor explicit. In the snippet you posted they use pattern matching, but one wouldn't want to export the implementation details, so unCompose is provided to use the contents of FComp. This is just the same as in data definitions, only that newtype wants exactly one field instead of 0..n.
You could write this:
newtype (FComp g f) x = FComp { unCompose :: g (f x) }
like so:
newtype FComp g f x = FComp (g (f x))
unCompose (FComp it) = it
This is so because type application has the same syntactic properties as ordinary applications, i.e.:
a b c = (a b) c
holds for values a,b,c and for types a,b,c.
Related
I'm stuck with Functor instance for composition of other functors in haskell.
data Cmps f g x = Cmps {getCmps :: f (g x)} deriving (Eq,Show)
--
instance (Functor f, Functor g) => Functor (Cmps f g) where
-- fmap :: (a -> b) -> (Cmps f g) a -> (Cmps f g) b
fmap = ?
In GHC.Generics functor just derived with {-# LANGUAGE DeriveFunctor #-}
-- | Composition of functors
infixr 7 :.:
newtype (:.:) f (g :: * -> *) (p :: *) = Comp1 { unComp1 :: f (g p) }
deriving (Eq, Ord, Read, Show, Functor, Generic, Generic1)`
I can't get some like fmap h (Cmps f g x) = Cmps f g (h x) becouse of error
The constructor ‘Cmps’ should have 1 argument, but has been given 3, and something like fmap h (f (g x)) don't work too. How can I get f, g and x from Cmps type in fmap implementation?
Consolidating the remarks by Li-yao Xia and orlan as an answer.
In your Cmps definition...
data Cmps f g x = Cmps {getCmps :: f (g x)} deriving (Eq,Show)
... f, g and x are type variables; they do not stand for fields. Cmps has a single field, of type f (g x). Accordingly, the fmap implementation for it should be:
instance (Functor f, Functor g) => Functor (Cmps f g) where
-- fmap :: (a -> b) -> (Cmps f g) a -> (Cmps f g) b
fmap h (Cmps x) = Cmps (fmap (fmap h) x)
If you want to compare that with an equivalent instance in the core libraries which is not derived, have a look at Compose from Data.Functor.Compose.
According to several sources, the Haskell implementation for composing functors is more or less the following:
import Data.Functor.Compose
newtype Compose f g a = Compose { getCompose :: f (g a) }
instance (Functor f, Functor g) => Functor (Compose f g) where
fmap f (Compose x) = Compose (fmap (fmap f) x)
My question is: what is the type of x in the last definition?
I'd say it is f g a, but even there I struggle to 'see' the computation fmap (fmap f) x
Could anyone be as kind as to provide a clear and complete working example of this point? What about fmapping a Tree of Maybe's paying attention to both Empty's and Node's?
Thank you in advance.
what is the type of x in the last definition?
Before saying anything else about the matter: you can ask GHC! GHC 7.8 and above supports TypedHoles, meaning that if you place an underscore in a expression (not pattern), and hit load or compile, you get a message with the expected type of the underscore and the types of the variables in local scope.
newtype Compose f g a = Compose { getCompose :: f (g a) }
instance (Functor f, Functor g) => Functor (Compose f g) where
fmap f (Compose x) = _
GHC says now, with some parts omitted:
Notes.hs:6:26: Found hole ‘_’ with type: Compose f g b …
-- omitted type variable bindings --
Relevant bindings include
x :: f (g a)
(bound at /home/kutta/home/Dropbox/src/haskell/Notes.hs:6:21)
f :: a -> b
(bound at /home/kutta/home/Dropbox/src/haskell/Notes.hs:6:10)
fmap :: (a -> b) -> Compose f g a -> Compose f g b
(bound at /home/kutta/home/Dropbox/src/haskell/Notes.hs:6:5)
In the expression: _
In an equation for ‘fmap’: fmap f (Compose x) = _
In the instance declaration for ‘Functor (Compose f g)’
There you go, x :: f (g a). And after some practice, TypedHoles can help you tremendously in figuring out complex polymorphic code. Let's try to figure out our current code out by writing out the right hand side from scratch.
We've already seen that the hole had type Compose f g b. Therefore we must have a Compose _ on the right side:
instance (Functor f, Functor g) => Functor (Compose f g) where
fmap f (Compose x) = Compose _
The new hole has type f (g b). Now we should look at the context:
Relevant bindings include
x :: f (g a)
(bound at /home/kutta/home/Dropbox/src/haskell/Notes.hs:6:21)
f :: a -> b
(bound at /home/kutta/home/Dropbox/src/haskell/Notes.hs:6:10)
fmap :: (a -> b) -> Compose f g a -> Compose f g b
(bound at /home/kutta/home/Dropbox/src/haskell/Notes.hs:6:5)
The goal is to get an f (g b) out of the ingredients in the context. The fmap in the listing above unfortunately refers to the function being defined, which is sometimes helpful, but not here. We're better off knowing that f and g are both functors, therefore they can be fmap-ed over. Since we have x :: f (g a), we guess that we should fmap something over x to get an f (g b):
fmap f (Compose x) = Compose (fmap _ x)
Now the hole becomes g a -> g b. But g a -> g b is very easy now, since we have f :: a -> b and g is a Functor, so we also have fmap :: (a -> b) -> g a -> g b, and therefore fmap f :: g a -> g b.
fmap f (Compose x) = Compose (fmap (fmap f) x)
And we're done.
To wrap up the technique:
Start with putting a hole in the place where you don't know how to proceed. Here we started with putting the hole in place of the entire right hand side, but often you will have a good idea about most parts of an implementation and you'll need the hole in a specific problematic subexpression.
By looking at the types, try to narrow down which implementations could possibly lead to the goal and which could not. Fill in a new expression and reposition the hole. In proof assistant jargon this is called "refining".
Repeat step 2 until you either have the goal, in which case you're done, or the current goal seems impossible, in which case backtrack until the last non-obvious choice you made, and try an alternative refining.
The above technique is sometimes facetiously called "type tetris". A possible drawback is that you can implement complex code just by playing the "tetris", without actually understanding what you're doing. And sometimes after going too far, you get seriously stuck in the game, and then you have to start actually thinking about the problem. But ultimately it lets you understand code that would be otherwise very difficult to grasp.
I personally use TypedHoles all the time and basically as a reflex. I've come to rely so much on it so that on a occasion when I had to move back to GHC 7.6 I felt rather uncomfortable (but fortunately you can emulate holes even there).
The type of x is f (g a). For example, x might be a list of trees of integers: [Tree Int] (which can also be written as [] (Tree Int) so that it matches f (g x) more closely).
As an example, consider function succ :: Int -> Int which adds one to an integer. Then, function fmap succ :: Tree Int -> Tree Int will increment every integer in the tree. Further, fmap (fmap succ) :: [Tree Int] -> [Tree Int] will apply the previous fmap succ to all the trees in a list, hence it will increment every integer in the list of trees.
If instead you have Tree (Maybe Int), then fmap (fmap succ) will increment every integer in such tree. Values in the tree of the form Nothing will not be affected, while values Just x will have x incremented.
Example: (GHCi session)
> :set -XDeriveFunctor
> data Tree a = Node a (Tree a) (Tree a) | Empty deriving (Show, Functor)
> let x1 = [Node 1 Empty Empty]
> fmap (fmap succ) x1
[Node 2 Empty Empty]
> let x2 = [Node 1 Empty Empty, Node 2 (Node 3 Empty Empty) Empty]
> fmap (fmap succ) x2
[Node 2 Empty Empty,Node 3 (Node 4 Empty Empty) Empty]
> let x3 = Just (Node 1 Empty Empty)
> fmap (fmap succ) x3
Just (Node 2 Empty Empty)
I am working my way through this tutorial. As documented in the tutorial, I copied some code as below, to represent functor composition and identity functor:
{-# LANGUAGE FlexibleContexts #-}
module Test where
newtype FComp f g a = C { unC :: f (g a) }
instance (Show (f (g a))) => Show (FComp f g a) where
show (C x) = "FComp " ++ show x
instance (Functor f, Functor g) => Functor (FComp f g) where
fmap h (C x) = C (fmap (fmap h) x)
newtype Id a = Identity { unId :: a } deriving Show
instance Functor Id where
fmap f x = Identity (f (unId x))
Now, this is what the tutorial states about identity functor:
Composition with the identity functor in the same category is as expected.
F∘IdB = F
IdA∘F = F
What I am stuck at is trying to think of it in terms of functor composition as represented by FComp in the code above. An example below:
$ let a = C (Identity (Just (5::Int)))
$ :t a
a :: FComp Id Maybe Int
$ let b = C (Just (Identity (5::Int)))
$ :t b
b :: FComp Maybe Id Int
I can't think of a way to assert that types of a and b as represented in example above are identical. I will appreciate pointers on how to think of identity functor in terms of functor composition.
Like many equations in Haskell-applied category theory, F ∘ IdB ≡ IdA ∘ F ≡ F should really just be read as equivalences. FComp Id Maybe Int is very much not the same thing as FComp Maybe Id Int to the type checker; however you can easily write
idFunctorIso :: Functor f => FComp f Id a -> f a
idFunctorIso (C fIdca) = fmap unId fIdca
idFunctorIso' :: Functor f => f a -> FComp f Id a
idFunctorIso' fa = C $ fmap Identity fIdc
which implies that both types contain the same information1. That's what we mean by saying they're isomorphic.
1No information is lost in either direction, since idFunctorIso' . idFunctorIso ≡ id (as follows from the functor law fmap id ≡ id, together with the fact that unC and unId are simple inverses of the newtype constructors).
Consider the following type:
data SomeType m a = SomeType (m Integer) [a]
We can easily make that type an instance of Functor with the following code:
instance Functor (SomeType m) where
fmap f (SomeType m lst) = SomeType m (map f lst)
However, if instead the params of the SomeType type were swapped:
data SomeType2 a m = SomeType2 (m Integer) [a]
Then the above instance definition doesn't work.
Is there some way of making SomeType2 an instance of Functor? If not, are there any up and coming additions to haskell/ghc that would make it possible?
Biased am I, but I think this is a great opportunity to make use of Control.Newtype, a little piece of kit that's a mere "cabal install newtype" away.
Here's the deal. You want to flip around type constructors to get your hands on functoriality (for example) in a different parameter. Define a newtype
newtype Flip f x y = Flip (f y x)
and add it to the Newtype class thus
instance Newtype (Flip f x y) (f y x) where
pack = Flip
unpack (Flip z) = z
The Newtype class is just a directory mapping newtypes to their unvarnished equivalents, providing handy kit, e.g. op Flip is the inverse of Flip: you don't need to remember what you called it.
For the problem in question, we can now do stuff like this:
data Bif x y = BNil | BCons x y (Bif x y) deriving Show
That's a two parameter datatype which happens to be functorial in both parameters. (Probably, we should make it an instance of a Bifunctor class, but anyway...) We can make it a Functor twice over: once for the last parameter...
instance Functor (Bif x) where
fmap f BNil = BNil
fmap f (BCons x y b) = BCons x (f y) (fmap f b)
...and once for the first:
instance Functor (Flip Bif y) where
fmap f (Flip BNil) = Flip BNil
fmap f (Flip (BCons x y b)) = Flip (BCons (f x) y (under Flip (fmap f) b))
where under p f is a neat way to say op p . f . p.
I tell you no lies: let us try.
someBif :: Bif Int Char
someBif = BCons 1 'a' (BCons 2 'b' (BCons 3 'c' BNil))
and then we get
*Flip> fmap succ someBif
BCons 1 'b' (BCons 2 'c' (BCons 3 'd' BNil))
*Flip> under Flip (fmap succ) someBif
BCons 2 'a' (BCons 3 'b' (BCons 4 'c' BNil))
In these circumstances, there really are many ways the same thing can be seen as a Functor, so it's right that we have to make some noise to say which way we mean. But the noise isn't all that much if you're systematic about it.
This isn't possible, and I don't think it will be anytime soon.
Order of type parameters is thus important. The last value is the one that you're going to "contain" for use with Functor, etc.
I tried to get this working by defining a type synonym that flipped the type parameters around and then used the TypeSynonymInstances extension, but it failed to work.
You can use a newtype wrapper which swaps the type parameters. But then you get a new type, and have to make a distinction of the original and the wrapped type in your code.
The dumb answer you already knew is: flip your parameters!
For GHC to support this sort of thing without any extra wrapping, you would need something like Type-level lambdas, which are probably not going to be added anytime soon. (I'd love to be proven wrong about that)
instance Functor (\a -> SomeType2 a m) where
-- fmap :: (a -> b) -> SomeType2 a m -> SomeType2 b m
fmap f (SomeType2 lst m) = SomeType (map f lst) m
Since we already have TypeSynonymInstances, we might be able to hope for PartiallyAppliedTypeSynonymInstances sometime slightly sooner than never.
type SomeType3 m a = SomeType2 a m
instance Functor (SomeType m) where
-- fmap :: (a -> b) -> SomeType3 m a -> SomeType3 m b
-- or, synonymously:
-- fmap :: (a -> b) -> SomeType2 a m -> SomeType2 a m
fmap f (SomeType2 lst m) = SomeType (map f lst) m
Parse error in pattern: f . g
i am a beginner, where is wrong?
(f . g) x = f (g x)
class Functor f where
fmap :: (a -> b) -> f a -> f b
class Functor g where
fmap :: (a -> b) -> f a -> f b
instance Functor F where
fmap id = id
fmap (f . g) = fmap f . fmap g
When you make an instance of Functor, you should prove the side condition that
fmap id = id
and
fmap (f . g) = fmap f . fmap g
(Technically the latter comes for free given the types involved and the former law, but it is still a good exercise.)
You can't do this just by saying
fmap id = id
but instead you use this as a reasoning tool -- once you have proven it.
That said, the code that you have written doesn't make sense for a number of reasons.
(f . g) x = f (g x)
Since this is indented, I'm somewhat unclear if this is intended to be a definition for (.), but that is already included in the Prelude, so you need not define it again.
class Functor f where
fmap :: (a -> b) -> f a -> f b
This definition is also provided for you in the Prelude.
class Functor g where
fmap :: (a -> b) -> f a -> f b
But then you define the class again, but here it has mangled the signature of fmap, which would have to be
fmap :: (a -> b) -> g a -> g b
But as you have another definition of Functor right above (and the Prelude has still another, you couldn't get that to compile)
Finally, your
instance Functor F where
fmap id = id
fmap (f . g) = fmap f . fmap g
makes up a name F for a type that you want to make into an instance of Functor, and then tries to give the laws as an implementation, which isn't how it works.
Let us take an example of how it should work.
Consider a very simple functor:
data Pair a = Pair a a
instance Functor Pair where
fmap f (Pair a b) = Pair (f a) (f b)
now, to prove fmap id = id, let us consider what fmap id and id do pointwise:
fmap id (Pair a b) = -- by definition
Pair (id a) (id b) = -- by beta reduction
Pair a (id b) = -- by beta reduction
Pair a b
id (Pair a b) = -- by definition
Pair a b
So, fmap id = id in this particular case.
Then you can check (though technically given the above, you don't have to) that fmap f . fmap g = fmap (f . g)
(fmap f . fmap g) (Pair a b) = -- definition of (.)
fmap f (fmap g (Pair a b)) = -- definition of fmap
fmap f (Pair (g a) (g b)) = -- definition of fmap
Pair (f (g a)) (f (g b))
fmap (f . g) (Pair a b) = -- definition of fmap
Pair ((f . g) a) ((f . g) b) = -- definition of (.)
Pair (f (g a)) ((f . g) b) = -- definition of (.)
Pair (f (g a)) (f (g b))
so fmap f . fmap g = fmap (f . g)
Now, you can make function composition into a functor.
class Functor f where
fmap :: (a -> b) -> f a -> f b
by partially applying the function arrow constructor.
Note that a -> b and (->) a b mean the same thing, so when we say
instance Functor ((->) e) where
the signature of fmap specializes to
fmap {- for (->) e -} :: (a -> b) -> (->) e a -> (->) e b
which once you have flipped the arrows around looks like
fmap {- for (->) e -} :: (a -> b) -> (e -> a) -> e -> b
but this is just the signature for function composition!
So
instance Functor ((->)e) where
fmap f g x = f (g x)
is a perfectly reasonable definition, or even
instance Functor ((->)e) where
fmap = (.)
and it actually shows up in Control.Monad.Instances.
So all you need to use it is
import Control.Monad.Instances
and you don't need to write any code to support this at all and you can use fmap as function composition as a special case, so for instance
fmap (+1) (*2) 3 =
((+1) . (*2)) 3 =
((+1) ((*2) 3)) =
((+1) (3 * 2)) =
3 * 2 + 1 =
7
Since . is not a data constructor you cannot use it for pattern matching I believe. As far as I can tell there isn't an easy way to do what you're trying, although I'm pretty new to Haskell as well.
let is not used for top-level bindings, just do:
f . g = \x -> f (g x)
But the complaint, as cobbal said, is about fmap (f . g), which isn't valid. Actually, that whole class Functor F where is screwy. The class is already declared, now I think you want to make and instance:
instance Functor F where
fmap SomeConstructorForF = ...
fmap OtherConstructorForF = ...
etc.