Domanda

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.

È stato utile?

Soluzione 2

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.

Altri suggerimenti

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top