# List notation

### From HaskellWiki

(Difference between revisions)

(there are cool things possible with bare list syntax) |
(non-empty constructor) |
||

(4 intermediate revisions by one user not shown) | |||

Line 24: | Line 24: | ||

[] | [] | ||

</haskell> | </haskell> | ||

− | * You can construct a singleton list with a [[operator | + | * You can insert elements or sub-lists conditionally. |

+ | <haskell> | ||

+ | infixr 5 ?:, ?++ | ||

+ | |||

+ | (?:) :: (Bool, a) -> [a] -> [a] | ||

+ | (?:) (b, x) = if b then (x:) else id | ||

+ | |||

+ | (?++) :: (Bool, [a]) -> [a] -> [a] | ||

+ | (?++) (b, x) = if b then (x++) else id | ||

+ | |||

+ | list = | ||

+ | [2,3] ++ | ||

+ | (x==5, 5) ?: | ||

+ | (x==7, listA) ?++ | ||

+ | [] | ||

+ | </haskell> | ||

+ | * You can construct a singleton list with a [[Section of an infix operator|section]] of the colon operator: <haskell>(:[]) :: a -> [a]</haskell>. | ||

* You can prepend an element to a list: <haskell>(x:) :: [a] -> [a]</haskell>. E.g. <haskell>iterate (' ':) []</haskell> creates a list of blank strings with increasing size very efficiently. | * You can prepend an element to a list: <haskell>(x:) :: [a] -> [a]</haskell>. E.g. <haskell>iterate (' ':) []</haskell> creates a list of blank strings with increasing size very efficiently. | ||

+ | * You can extend the scheme by more constructors, as in {{HackagePackage|id=non-empty}}. | ||

+ | : | ||

+ | <haskell> | ||

+ | data NonEmpty f a = a :! f a | ||

+ | |||

+ | infixr 5 :! | ||

+ | |||

+ | example :: NonEmpty (NonEmpty []) Int | ||

+ | example = 0 :! 1 :! 2 : 3 : 4 : [] | ||

+ | </haskell> | ||

+ | :You can use the <hask>example</hask> list in situations where you need to prove that the list contains at least two elements. | ||

+ | * You can adapt this style to other list-like data structures, e.g. a list of elements with alternating element types. See e.g. {{HackagePackage|id=event-list}}. | ||

+ | : | ||

+ | <haskell> | ||

+ | data Alternating a b = Alternating a [(b,a)] | ||

+ | |||

+ | infixr 5 /., ./ | ||

+ | |||

+ | (/.) :: a -> [(b,a)] -> Alternating a b | ||

+ | (/.) = Alternating | ||

+ | |||

+ | (./) :: b -> Alternating a b -> [(b,a)] | ||

+ | b ./ Alternating a bas = (b,a) : bas | ||

+ | |||

+ | example :: Alternating Bool Int | ||

+ | example = True /. 0 ./ False /. 1 ./ True /. [] | ||

+ | </haskell> | ||

+ | |||

+ | == See also == | ||

− | |||

* [http://www.haskell.org/pipermail/haskell-cafe/2006-July/016655.html Haskell-Cafe thread: Comma in the front] | * [http://www.haskell.org/pipermail/haskell-cafe/2006-July/016655.html Haskell-Cafe thread: Comma in the front] | ||

[[Category:Idioms]] | [[Category:Idioms]] | ||

[[Category:Syntax]] | [[Category:Syntax]] |

## Latest revision as of 17:33, 10 January 2014

We are used to the list notation[0,1,2,3]

(0:1:2:3:[])

By using the syntactic sugar, we often miss the benefits of the direct notation.

- A trailing colon is like a terminator.

0 : 1 : 2 : 3 : []

- Thus it is more theoretically sound and easier to edit.

- You can easily mix elements and lists into a list by appending the corresponding operator in each line:

[1,2,3] ++ 4 : listA ++ 5 : listB ++ []

- You can insert elements or sub-lists conditionally.

infixr 5 ?:, ?++ (?:) :: (Bool, a) -> [a] -> [a] (?:) (b, x) = if b then (x:) else id (?++) :: (Bool, [a]) -> [a] -> [a] (?++) (b, x) = if b then (x++) else id list = [2,3] ++ (x==5, 5) ?: (x==7, listA) ?++ []

- You can construct a singleton list with a section of the colon operator: .
(:[]) :: a -> [a]

- You can prepend an element to a list: . E.g.
(x:) :: [a] -> [a]

creates a list of blank strings with increasing size very efficiently.iterate (' ':) []

- You can extend the scheme by more constructors, as in non-empty.

data NonEmpty f a = a :! f a infixr 5 :! example :: NonEmpty (NonEmpty []) Int example = 0 :! 1 :! 2 : 3 : 4 : []

- You can use the list in situations where you need to prove that the list contains at least two elements.example

- You can adapt this style to other list-like data structures, e.g. a list of elements with alternating element types. See e.g. event-list.

data Alternating a b = Alternating a [(b,a)] infixr 5 /., ./ (/.) :: a -> [(b,a)] -> Alternating a b (/.) = Alternating (./) :: b -> Alternating a b -> [(b,a)] b ./ Alternating a bas = (b,a) : bas example :: Alternating Bool Int example = True /. 0 ./ False /. 1 ./ True /. []