I'm Having problems understanding functors, specifically what a concrete type is in LYAH. I believe this is because I don't understand what []
really is.
fmap :: (a -> b) -> f a -> f b
[]
, a type-constructor? Or, is it a value constructor?[] :: [a]
?Maybe
type-constructor, or Just
value constructor?Just
then how come Just
has a signature like Just :: a -> Maybe a
rather than Just :: Maybe a
, in other words why isn't []
typed [] :: a -> [a]
fmap :: (a -> b) -> f a -> f b
, we see that the f has to be a type constructor that takes one type. [a]
is already a concrete type (of a list with any type inside it), while []
is a type constructor that takes one type and can produce types such as [Int]
, [String]
or even [[String]]
. I'm confused though the type of []
implies it is like a literal for [a]
what is LYAH trying to get at?Data constructors are first class values in Haskell and actually have a type. For instance, the type of the Left constructor of the Either data type is: Left :: a -> Either a b. As first class values, they may be passed to functions, held in a list, be data elements of other algebraic data types and so forth.
In Haskell, lists are a homogenous data structure. It stores several elements of the same type. That means that we can have a list of integers or a list of characters but we can't have a list that has a few integers and then a few characters. And now, a list!
The type is described (in a GHCI session) as:
$ ghci Prelude> :info [] data [] a = [] | a : [a] -- Defined
We may also think about it as though it were defined as:
data List a = Nil | Cons a (List a)
or
data List a = EmptyList | ListElement a (List a)
Type Constructor
[a]
is a polymorphic data type, which may also be written [] a
as above. This may be thought about as though it were List a
In this case, []
is a type constructor taking one type argument a
and returning the type [] a
, which is also permitted to be written as [a]
.
One may write the type of a function like:
sum :: (Num a) => [a] -> a
Data Constructor
[]
is a data constructor which essentially means "empty list." This data constructor takes no value arguments.
There is another data constructor, :
, which prepends an element to the front of another list. The signature for this data constructor is a : [a]
- it takes an element and another list of elements and returns a resultant list of elements.
The []
notation may also be used as shorthand for constructing a list. Normally we would construct a list as:
myNums = 3 : 2 : 4 : 7 : 12 : 8 : []
which is interpreted as
myNums = 3 : (2 : (4 : (7 : (12 : (8 : [])))))
but Haskell permits us also to use the shorthand
myNums = [ 3, 2, 4, 7, 12, 8 ]
as an equivalent in meaning, but slightly nicer in appearance, notation.
Ambiguous Case
There is an ambiguous case that is commonly seen: [a]
. Depending on the context, this notation can mean either "a list of a
's" or "a list with exactly one element, namely a
." The first meaning is the intended meaning when [a]
appears within a type, while the second meaning is the intended meaning when [a]
appears within a value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With