softshipper
softshipper

Reputation: 34119

Type signature as function

I have following type constructor and data constructor:

data Compose f g x = MkCompose (f (g x))

Get type signature in the prelude about Compose, it shows:

MkCompose :: f (g x) -> Compose f g x

Why it shows like a function?

When I apply the type as following:

*ComposeExercise> :t MkCompose [[42]]
MkCompose [[42]] :: Num x => Compose [] [] x

Then for me, it is clear.

Upvotes: 0

Views: 67

Answers (1)

AJF
AJF

Reputation: 11923

When you write:

data Compose f g x = MkCompose (f (g x))

You are saying that:

MkCompose :: f (g x) -> Compose f g x

That is the definition of Compose; this is what a data declaration does.

However, when you give it an argument (since it is a function), like the following, f, g, and x are given specific types:

λ> :t MkCompose [[1]]                    -- f = [], g = [], x = Num n => n.
MkCompose 1 :: Num n => Compose [] [] n  -- As in the definition.

MkCompose has a function type exactly because it is a function; it takes a value and returns another.

If this isn't clear, here are some other examples:

  • MkCompose (Just [1]) :: Num n => Compose Maybe [] n, since Just [1] :: Num n => Maybe [n]. In this case, f = Maybe, g = [], and x = Num n => n.
  • MkCompose getLine :: Compose IO [] Char, since getLine :: IO [Char]. In this case, f = IO, g = [], and x = Char.
  • MkCompose [[]] :: Compose [] [] x, since [[]] :: [[x]]. In this case, f = [], g = [], but x can be anything.

Upvotes: 4

Related Questions