📜 ⬆️ ⬇️

About Haskell Names

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 --   a ### b = a * b --      (@@@) :: Int -> Int -> Int --   (@@@) a = (a +) --      myFunc :: Int -> Int -> Int --   a `myFunc` b = a * b --      myFunc' :: Int -> Int -> Int --   myFunc' a = (a -) --      


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 constructors
from 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 --   --  : = XLeft a | XRight b | (a @# b) :$% (a @# b) | (a @# b) :!~ (a @# b) | (:!~>) (a @# b) (a @# b) (a @# b) deriving Show 

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 

UPD
Function 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.

Source: https://habr.com/ru/post/248685/


All Articles