Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell newtype with parentheses

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.

like image 816
Felix Benner Avatar asked Jul 25 '13 08:07

Felix Benner


People also ask

What does Newtype mean in Haskell?

One of the most common and useful Haskell features is newtype . newtype is an ordinary data type with the name and a constructor. However, you can define a data type as newtype instead of data only if it has exactly one constructor with exactly one field.

What is a point in Haskell?

In Haskell, our 'space' is some type, and 'points' are values. In the declaration. f x = x + 1. we define the function f in terms of its action on an arbitrary point x .


2 Answers

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.

like image 45
Ingo Avatar answered Sep 28 '22 00:09

Ingo


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.

like image 81
firefrorefiddle Avatar answered Sep 28 '22 00:09

firefrorefiddle