F#: why to have both '::' and '@'

  • A+

I started to read about F# recently, and obviously I got one novice-level question very soon. It is about lists (collections).

According to F# manuals, there are two operations to construct lists, they are cons (aka ::) and @. Given the fact @ is more versatile (can merge sublists, not single elements, and can append to the tail as well, unlike the cons operation), my question is: at which situation we must use exactly :: instead of @ to avoid ambiguity, or non-wanted side-effects and so on?

In other words: is :: theoretically redundant or not?

The list type has two constructors: [] and ::. If :: were removed, only the [] constructor would be left, making it impossible to create non-empty lists.

Note that something like [1;2;3] is syntactic sugar for 1::2::3::[], so it relies on the existence of ::.

Similarly, @ is a function that's defined using ::, so if :: didn't exist, neither could @.

Note that @ isn't suitable as a replacement for :: in list's definition as, if you don't already have a way to construct non-empty lists, @ can't be used to create them ([] @ [] is still an empty list).

And even if you added a constructor for single-item lists, @ would lead to an ambiguous representation because [1;2;3] could be represented either as ([1] @ [2]) @ [3] or as [1] @ ([2] @ [3]) (plus, you could just add @ [] anywhere you want). So you'd end up with several different representations for semantically equivalent lists.


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: