The name of any
identifier in Haskell begins with the letter followed by
zero or more letters, numbers, underscores, and single quotes'. Only Latin characters in the intervals a..z and A..Z are considered as letters. The symbol _ is considered to be a
letter , as a result of which the
function name can begin with this symbol, but cannot consist only of it, since it means
any value in Haskell
samples .
Function names that are not composed of ascSymbol characters must
necessarily begin with a lowercase letter or the _ character. Names of namespaces, data types, data constructors, and type classes
composed of non-ascSymbol characters must begin with a capital letter. This note provides some information about using ascSymbol characters in Haskell identifiers.
"Special symbols
According to § 2.2 of Haskell 2010, the following characters are considered special (special):
(
)
,
;
[
]
`
{
}
The following set of characters, named ascSymbol, is also defined separately there:
!
#
$
%
&
*
+
.
/
<
=
>
?
@
\
ˆ
|
-
˜
:
Alphanumeric characters in the standard are separated into separate sets: ascSmall, ascLarge,
uniSmall, uniLarge, ascDigit, uniDigit, etc.
')
Sometimes,
special characters are mistakenly called characters included in the ascSymbol set. For example, defining the operator
sometimes they say their names are
from special characters only . In fact, special characters cannot be used as part of operator names (and generally as part of any names).
From the characters in the ascSymbol set, it is allowed to form any names except for the following
reserved :
..
:
::
=
\
|
<-
->
@
~
=>
Function or operator?
Operator in Haskell is called
any function, called
in infix form, or partially applied by means of
sections . So whether this or that function can be called an operator
depends on the context of its use . In the following examples, the functions
elem
and
*
are operators:
λ: 5 `elem` [0..10] True λ: 4 * 10 40
Some user-defined function to use as sections:
mySomeFunc :: Integral a => a -> a -> a _ `mySomeFunc` 0 = error "Zero division." a `mySomeFunc` b = a `div` b
We use the function
mySomeFunc
as sections, i.e. in this context, it is an operator:
λ: let n = (8 `mySomeFunc`) λ: let m = (`mySomeFunc` 2) λ: n 2 4 λ: m 10 5
The function
called in the prefix notation is not an operator
in this usage context . In the following examples, the functions
elem
and
*
are
not operators:
λ: elem 5 [0..10] True λ: (*) 4 10 40
Infix and prefix forms
If the function name consists of ascSymbol characters, then when specifying its
signature, such a name must be enclosed in parentheses.
(###) :: Int -> Int -> Int
If the function name consists of ascSymbol characters, and its definition is given in the
prefix notation, then this name must also be specified in parentheses.
(@@@) a = (a +)
If the function name
does not consist of the ascSymbol characters, and its definition is given in the
infix form of the record, then the name must be enclosed with return quotation marks `.
a `myFunc` b = a * b
Examples of using infix and prefix forms of records in the function
definition code:
(###) :: Int -> Int -> Int
In infix form, you can call
any function, the number of parameters of which is more than one, for example:
λ: ((+) `foldr` 0) [1..10] 55
Or, for example, a function that takes four parameters:
someFunc :: Int -> Int -> Int -> Int -> Int someFunc abcd = a + b + c + d
Prefix and infix variants of its call:
λ: someFunc 1 2 3 4 10 λ: (1 `someFunc` 2) 3 4 10
Data constructor names
As noted above, the
names of data constructors begin with a capital letter, consist of alphanumeric characters, as well as the symbols _ and '(if necessary). However, a naming system is allowed,
similar to the one that
applies to functions ...
Haskell standard is allowed to form the names
of data constructorsfrom the characters in the ascSymbol set. Like ordinary functions, such constructors can be used both in infix and in
prefix form. In addition, their names must begin with the symbol: (colon).
Those. if you saw something in the code somewhere
like
123 :#$% "ASDF"
, then immediately you can be sure that you have a constructor call: # $% with parameters
123 and "ASDF".
data Symbolic n = Constant n | Variable String | Symbolic n :=> Symbolic n | Symbolic n :<= Symbolic n | (:<=>) (Symbolic n) (Symbolic n) deriving Show
Let's create several instances of
Symbolic
type in ghci using different data constructors:
λ: let a = Constant 10; b = Variable "Hello" λ: let n = a :=> b; m = a :<= b; k = a :<=> b λ: n Constant 10 :=> Variable "Hello" λ: m Constant 10 :<= Variable "Hello" λ: k (:<=>) (Constant 10) (Variable "Hello")
Type Constructor Names
By default , type constructor names
cannot consist of ascSymbol characters. However, you can
force the use of such names for type constructors. This is done either by specifying the option
-XTypeOperators when calling ghc or ghci, or by adding the following line to the beginning of the hs-file:
{-# LANGUAGE TypeOperators #-}
Unlike the data constructor, the name
of the type constructor does not have to begin with the symbol: (colon).
{-# LANGUAGE TypeOperators #-} data a @# b
We try to create instances of our data type:
λ: let a = XLeft 10; b = XRight "ABCD" λ: let c = a :$% b; d = b :!~ a; λ: let e = (:!~>) aaa λ: c XLeft 10 :$% XRight "ABCD" λ: d XRight "ABCD" :!~ XLeft 10 λ: e (:!~>) (XLeft 10) (XLeft 10) (XLeft 10)
Pattern Names
Pattern names may also consist of ascSymbol characters.
λ: let ($%%) = (*) λ: :t ($%%) ($%%) :: Num a => a -> a -> a λ: 5 $%% 2 10 λ: ($%%) 3 4 12 λ: let (###) = (3 +) λ: (###) 2 5
UPDFunction names can be assigned using other Unicode characters. For example, in books it is sometimes possible to find symbols of
mathematical operators as names of functions. For example, you can write this function:
(∀) :: (a -> b) -> [a] -> [b] f ∀ [] = [] f ∀ (x:xs) = fx : f ∀ xs
This function will successfully load into
ghci , but it will be problematic to call it, since in
cmd.exe and
powershell.exe it can be difficult to type
∀ in the command line. I did not manage to do this through the clipboard (the corresponding item in the context menu) or through the key combination (
Alt + 8704 ). The use of the
Lucida console font and a preliminary call to the
chcp.com 65001 command
does not help
either .
However, in some books, you can see the very active use of mathematical symbols as function names in Haskell source code. For example, in
Richard Bird's book, Pearls of Algorithm Design. Functional approach. With examples on Haskell " .
Summing up
If this is not about functions, then you are unlikely to use ascSymbol characters in identifier names. However, knowing how they can be applied beyond function names will help you understand the code in which they are used for some reason.