Reputation: 34119
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
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