Constructors vs functions
Constructors make new data types out of old data. Let's roll our own list:
data List a = Empty | Cons a (List a)
myList = Const 1 (Cons 2 Empty) -- 1:2:[] =[1,2]
uncons x' (Cons x xs) = if x == x' then xs else Cons x xs
Here, Cons :: a -> List a
is a special function that takes an element and a list and makes a longer list.
It's important that there's a difference between constructor functions and ordinary functions, so that the compiler knows which one is valid in a pattern match:
headM (Cons x xs) = Just x
headM Empty = Nothing
That makes sense, but this doesn't:
previousHead (uncons x xs) = Just x
previousHead xs = Nothing
because how can the computer know which element you removed or whether you did remove one?
Infix Constructors and functions
Sometimes, as with lists, it's helpful to have a constructor work infix, so we actually have the equivalent of
data [a] = [] | a:[a]
so we can write lists like 1:2:[]
.
Infix functions need to be separate from identifiers so we can write x:xs
unambiguously without spaces, so infix functions (including infix constructors like :
have to consist entirely of symbols, not letters.
The compiler still needs to be able to tell constructors apart from ordinary functions when they're infix, so we need the equivalent of the rule that constructors start with a capital. The language designers designated :
as the only capital symbol, so infix constructors have to start with it, and ordinary functions can't.
What you can do with :=
You can use :=
as a constructor, so you could define
data Assignment a = Variable := Expression a
But if you want to call an ordinary function :=
, you can't, because :
isn't allowed at the front as it counts as the capital symbol, you'd have to start with something else, for (simple but pointless) example:
(.:=) :: Maybe a -> a -> Maybe a
Nothing .:= x = Just x
Just y .:= x = Just x