Safe Haskell | None |
---|---|
Language | Haskell2010 |
Tons of useful functions that get imported by default.
Synopsis
- type Int = Int64
- type Float = Double
- (+) :: Num number => number -> number -> number
- (-) :: Num number => number -> number -> number
- (*) :: Num number => number -> number -> number
- (/) :: Float -> Float -> Float
- (//) :: Int -> Int -> Int
- (^) :: Float -> Float -> Float
- toFloat :: Int -> Float
- round :: Float -> Int
- floor :: Float -> Int
- ceiling :: Float -> Int
- truncate :: Float -> Int
- (==) :: Eq a => a -> a -> Bool
- (/=) :: Eq a => a -> a -> Bool
- (<) :: Ord comparable => comparable -> comparable -> Bool
- (>) :: Ord comparable => comparable -> comparable -> Bool
- (<=) :: Ord comparable => comparable -> comparable -> Bool
- (>=) :: Ord comparable => comparable -> comparable -> Bool
- max :: Ord comparable => comparable -> comparable -> comparable
- min :: Ord comparable => comparable -> comparable -> comparable
- compare :: Ord comparable => comparable -> comparable -> Order
- type Order = Ordering
- data Ordering
- data Bool
- not :: Bool -> Bool
- (&&) :: Bool -> Bool -> Bool
- (||) :: Bool -> Bool -> Bool
- xor :: Bool -> Bool -> Bool
- (++) :: Semigroup appendable => appendable -> appendable -> appendable
- modBy :: Int -> Int -> Int
- remainderBy :: Int -> Int -> Int
- negate :: Num number => number -> number
- abs :: Num number => number -> number
- clamp :: Ord number => number -> number -> number -> number
- sqrt :: Float -> Float
- logBase :: Float -> Float -> Float
- e :: Float
- degrees :: Float -> Float
- radians :: Float -> Float
- turns :: Float -> Float
- pi :: Float
- cos :: Float -> Float
- sin :: Float -> Float
- tan :: Float -> Float
- acos :: Float -> Float
- asin :: Float -> Float
- atan :: Float -> Float
- atan2 :: Float -> Float -> Float
- toPolar :: (Float, Float) -> (Float, Float)
- fromPolar :: (Float, Float) -> (Float, Float)
- isNaN :: Float -> Bool
- isInfinite :: Float -> Bool
- identity :: a -> a
- always :: a -> b -> a
- (<|) :: (a -> b) -> a -> b
- (|>) :: a -> (a -> b) -> b
- (<<) :: (b -> c) -> (a -> b) -> a -> c
- (>>) :: (a -> b) -> (b -> c) -> a -> c
- type Never = Void
- never :: Never -> a
- class Eq a
- class Eq a => Ord a
- class Num a
Math
An Int
is a whole number. Valid syntax for integers includes:
0 42 9000 0xFF -- 255 in hexadecimal 0x000A -- 10 in hexadecimal
Note: Int
math is well-defined in the range -2^31
to 2^31 - 1
.
Historical Note: The name Int
comes from the term integer. It appears that the int
abbreviation was introduced in ALGOL 68, shortening it from integer
in ALGOL 60. Today, almost all programming languages use this abbreviation.
A Float
is a floating-point number. Valid syntax for floats includes:
0 42 3.14 0.1234 6.022e23 -- == (6.022 * 10^23) 6.022e+23 -- == (6.022 * 10^23) 1.602e-19 -- == (1.602 * 10^-19) 1e3 -- == (1 * 10^3) == 1000
Historical Note: The particular details of floats (e.g. NaN
) are
specified by IEEE 754 which is
literally hard-coded into almost all CPUs in the world. That means if you
think NaN
is weird, you must successfully overtake Intel and AMD with a
chip that is not backwards compatible with any widely-used assembly
language.
(+) :: Num number => number -> number -> number infixl 6 Source #
Add two numbers. The number
type variable means this operation can be
specialized to Int -> Int -> Int
or to Float -> Float -> Float
. So you
can do things like this:
3002 + 4004 == 7006 -- all ints 3.14 + 3.14 == 6.28 -- all floats
You _cannot_ add an Int
and a Float
directly though. Use functions like
toFloat
or round
to convert both values to the same type. So if you
needed to add a list length to a Float
for some reason, you could say one
of these:
3.14 + toFloat (List.length [1,2,3]) == 6.14 round 3.14 + List.length [1,2,3] == 6
Note: Languages like Java and JavaScript automatically convert Int
values to Float
values when you mix and match. This can make it difficult
to be sure exactly what type of number you are dealing with. When you try to
infer these conversions (as Scala does) it can be even more confusing. Elm
has opted for a design that makes all conversions explicit.
(-) :: Num number => number -> number -> number infixl 6 Source #
Subtract numbers like 4 - 3 == 1
.
See
for docs on the (+)
number
type variable.
(*) :: Num number => number -> number -> number infixl 7 Source #
Multiply numbers like 2 * 3 == 6
.
See
for docs on the (+)
number
type variable.
(//) :: Int -> Int -> Int infixl 7 Source #
Integer division:
3 // 2 == 1
Notice that the remainder is discarded.
(^) :: Float -> Float -> Float infixr 8 Source #
Exponentiation
3^2 == 9 3^3 == 27
Breaking from Elm here, in that this is only defined for Float
arguments.
The exponentiation story in Haskell is a little more complex. See the (^)
,
(^^)
, and (__)
operations as a starting point.
toFloat :: Int -> Float Source #
Convert an integer into a float. Useful when mixing Int
and Float
values like this:
halfOf :: Int -> Float halfOf number = toFloat number / 2
round :: Float -> Int Source #
Round a number to the nearest integer.
round 1.0 == 1 round 1.2 == 1 round 1.5 == 2 round 1.8 == 2
round -1.2 == -1 round -1.5 == -1 round -1.8 == -2
floor :: Float -> Int Source #
Floor function, rounding down.
floor 1.0 == 1 floor 1.2 == 1 floor 1.5 == 1 floor 1.8 == 1
floor -1.2 == -2 floor -1.5 == -2 floor -1.8 == -2
ceiling :: Float -> Int Source #
Ceiling function, rounding up.
ceiling 1.0 == 1 ceiling 1.2 == 2 ceiling 1.5 == 2 ceiling 1.8 == 2
ceiling -1.2 == -1 ceiling -1.5 == -1 ceiling -1.8 == -1
truncate :: Float -> Int Source #
Truncate a number, rounding towards zero.
truncate 1.0 == 1 truncate 1.2 == 1 truncate 1.5 == 1 truncate 1.8 == 1
truncate -1.2 == -1 truncate -1.5 == -1 truncate -1.8 == -1
Equality
(==) :: Eq a => a -> a -> Bool infix 4 Source #
Check if values are “the same”.
Breaking from Elm, this relies on Haskell's Eq
typeclass. For example:
data Foo = Bar | Baz deriving (Eq)
(/=) :: Eq a => a -> a -> Bool infix 4 Source #
Check if values are not “the same”.
Like with (==)
, this relies on Haskell's Eq
typeclass.
So (a /= b)
is the same as (not (a == b))
.
Comparison
These functions only work on Order
-able types. This includes numbers,
characters, strings, lists of comparable things, and tuples of comparable
things.
max :: Ord comparable => comparable -> comparable -> comparable Source #
Find the larger of two comparables.
max 42 12345678 == 12345678 max "abc" "xyz" == "xyz"
min :: Ord comparable => comparable -> comparable -> comparable Source #
Find the smaller of two comparables.
min 42 12345678 == 42 min "abc" "xyz" == "abc"
compare :: Ord comparable => comparable -> comparable -> Order Source #
Compare any two comparable values. Comparable values include String
,
Char
, Int
, Float
, or a list or tuple containing comparable values. These
are also the only values that work as Dict
keys or Set
members.
compare 3 4 == LT compare 4 4 == EQ compare 5 4 == GT
type Order = Ordering Source #
Represents the relative ordering of two things. The relations are less than, equal to, and greater than.
Instances
Bounded Ordering | Since: base-2.1 |
Enum Ordering | Since: base-2.1 |
Eq Ordering | |
Ord Ordering | |
Defined in GHC.Classes | |
Read Ordering | Since: base-2.1 |
Show Ordering | Since: base-2.1 |
Generic Ordering | Since: base-4.6.0.0 |
Semigroup Ordering | Since: base-4.9.0.0 |
Monoid Ordering | Since: base-2.1 |
Hashable Ordering | |
Defined in Data.Hashable.Class | |
ToJSON Ordering | |
Defined in Data.Aeson.Types.ToJSON | |
type Rep Ordering | |
Booleans
Instances
(&&) :: Bool -> Bool -> Bool infixr 3 Source #
The logical AND operator. True
if both inputs are True
.
True && True == True True && False == False False && True == False False && False == False
(||) :: Bool -> Bool -> Bool infixr 2 Source #
The logical OR operator. True
if one or both inputs are True
.
True || True == True True || False == True False || True == True False || False == False
xor :: Bool -> Bool -> Bool Source #
The exclusive-or operator. True
if exactly one input is True
.
xor True True == False xor True False == True xor False True == True xor False False == False
Append Strings and Lists
(++) :: Semigroup appendable => appendable -> appendable -> appendable infixr 5 Source #
Put two appendable things together. This includes strings, lists, and text.
"hello" ++ "world" == "helloworld" [1,1,2] ++ [3,5,8] == [1,1,2,3,5,8]
Fancier Math
modBy :: Int -> Int -> Int Source #
Perform modular arithmetic. A common trick is to use (n mod 2) to detect even and odd numbers:
modBy 2 0 == 0 modBy 2 1 == 1 modBy 2 2 == 0 modBy 2 3 == 1
Our modBy
function works in the typical mathematical way when you run into
negative numbers:
List.map (modBy 4) [ -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5 ] -- [ 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1 ]
Use 'remainderBy
' for a different treatment of negative numbers, or read Daan Leijen’s Division and Modulus for Computer Scientists for more information.
remainderBy :: Int -> Int -> Int Source #
Get the remainder after division. Here are bunch of examples of dividing by four:
List.map (remainderBy 4) [ -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5 ] -- [ -1, 0, -3, -2, -1, 0, 1, 2, 3, 0, 1 ]
Use 'modBy
' for a different treatment of negative numbers, or read Daan Leijen’s Division and Modulus for Computer Scientists for more information.
negate :: Num number => number -> number Source #
Negate a number.
negate 42 == -42 negate -42 == 42 negate 0 == 0
abs :: Num number => number -> number Source #
Get the absolute value of a number.
abs 16 == 16 abs -4 == 4 abs -8.5 == 8.5 abs 3.14 == 3.14
clamp :: Ord number => number -> number -> number -> number Source #
Clamps a number within a given range. With the expression
clamp 100 200 x
the results are as follows:
100 if x < 100 x if 100 <= x < 200 200 if 200 <= x
sqrt :: Float -> Float Source #
Take the square root of a number.
sqrt 4 == 2 sqrt 9 == 3 sqrt 16 == 4 sqrt 25 == 5
logBase :: Float -> Float -> Float Source #
Calculate the logarithm of a number with a given base.
logBase 10 100 == 2 logBase 2 256 == 8
Angles
degrees :: Float -> Float Source #
Convert degrees to standard Elm angles (radians).
degrees 180 == 3.141592653589793
radians :: Float -> Float Source #
Convert radians to standard Elm angles (radians).
radians pi == 3.141592653589793
turns :: Float -> Float Source #
Convert turns to standard Elm angles (radians). One turn is equal to 360°.
turns (1/2) == 3.141592653589793
Trigonometry
cos :: Float -> Float Source #
Figure out the cosine given an angle in radians.
cos (degrees 60) == 0.5000000000000001 cos (turns (1/6)) == 0.5000000000000001 cos (radians (pi/3)) == 0.5000000000000001 cos (pi/3) == 0.5000000000000001
sin :: Float -> Float Source #
Figure out the sine given an angle in radians.
sin (degrees 30) == 0.49999999999999994 sin (turns (1/12)) == 0.49999999999999994 sin (radians (pi/6)) == 0.49999999999999994 sin (pi/6) == 0.49999999999999994
tan :: Float -> Float Source #
Figure out the tangent given an angle in radians.
tan (degrees 45) == 0.9999999999999999 tan (turns (1/8)) == 0.9999999999999999 tan (radians (pi/4)) == 0.9999999999999999 tan (pi/4) == 0.9999999999999999
acos :: Float -> Float Source #
Figure out the arccosine for adjacent / hypotenuse
in radians:
acos (1/2) == 1.0471975511965979 -- 60° or pi/3 radians
asin :: Float -> Float Source #
Figure out the arcsine for opposite / hypotenuse
in radians:
asin (1/2) == 0.5235987755982989 -- 30° or pi/6 radians
atan :: Float -> Float Source #
This helps you find the angle (in radians) to an (x,y)
coordinate, but
in a way that is rarely useful in programming. __You probably want
atan2
instead!__
This version takes y/x
as its argument, so there is no way to know whether
the negative signs comes from the y
or x
value. So as we go counter-clockwise
around the origin from point (1,1)
to (1,-1)
to (-1,-1)
to (-1,1)
we do
not get angles that go in the full circle:
atan ( 1 / 1 ) == 0.7853981633974483 -- 45° or pi/4 radians atan ( 1 / -1 ) == -0.7853981633974483 -- 315° or 7*pi/4 radians atan ( -1 / -1 ) == 0.7853981633974483 -- 45° or pi/4 radians atan ( -1 / 1 ) == -0.7853981633974483 -- 315° or 7*pi/4 radians
Notice that everything is between pi/2
and -pi/2
. That is pretty useless
for figuring out angles in any sort of visualization, so again, check out
atan2
instead!
atan2 :: Float -> Float -> Float Source #
This helps you find the angle (in radians) to an (x,y)
coordinate.
So rather than saying atan (y/x)
you say atan2 y x
and you can get a full
range of angles:
atan2 1 1 == 0.7853981633974483 -- 45° or pi/4 radians atan2 1 -1 == 2.356194490192345 -- 135° or 3*pi/4 radians atan2 -1 -1 == -2.356194490192345 -- 225° or 5*pi/4 radians atan2 -1 1 == -0.7853981633974483 -- 315° or 7*pi/4 radians
Polar Coordinates
toPolar :: (Float, Float) -> (Float, Float) Source #
Convert Cartesian coordinates (x,y) to polar coordinates (r,θ).
toPolar (3, 4) == ( 5, 0.9272952180016122) toPolar (5,12) == (13, 1.1760052070951352)
fromPolar :: (Float, Float) -> (Float, Float) Source #
Convert polar coordinates (r,θ) to Cartesian coordinates (x,y).
fromPolar (sqrt 2, degrees 45) == (1, 1)
Floating Point Checks
isNaN :: Float -> Bool Source #
Determine whether a float is an undefined or unrepresentable number. NaN stands for *not a number* and it is a standardized part of floating point numbers.
isNaN (0/0) == True isNaN (sqrt -1) == True isNaN (1/0) == False -- infinity is a number isNaN 1 == False
isInfinite :: Float -> Bool Source #
Determine whether a float is positive or negative infinity.
isInfinite (0/0) == False isInfinite (sqrt -1) == False isInfinite (1/0) == True isInfinite 1 == False
Notice that NaN is not infinite! For float n
to be finite implies that
not (isInfinite n || isNaN n)
evaluates to True
.
Function Helpers
Given a value, returns exactly the same value. This is called the identity function.
always :: a -> b -> a Source #
Create a function that *always* returns the same value. Useful with
functions like map
:
List.map (always 0) [1,2,3,4,5] == [0,0,0,0,0]
-- List.map (\_ -> 0) [1,2,3,4,5] == [0,0,0,0,0] -- always = (\x _ -> x)
(<|) :: (a -> b) -> a -> b infixr 0 Source #
Saying f <| x
is exactly the same as f x
.
It can help you avoid parentheses, which can be nice sometimes. Maybe you want
to apply a function to a case
expression? That sort of thing.
(|>) :: a -> (a -> b) -> b infixl 0 Source #
Saying x |> f
is exactly the same as f x
.
It is called the “pipe” operator because it lets you write “pipelined” code.
For example, say we have a sanitize
function for turning user input into
integers:
-- BEFORE sanitize :: String -> Maybe Int sanitize input = String.toInt (String.trim input)
We can rewrite it like this:
-- AFTER sanitize :: String -> Maybe Int sanitize input = input |> String.trim |> String.toInt
Totally equivalent! I recommend trying to rewrite code that uses x |> f
into code like f x
until there are no pipes left. That can help you build
your intuition.
Note: This can be overused! I think folks find it quite neat, but when you have three or four steps, the code often gets clearer if you break out a top-level helper function. Now the transformation has a name. The arguments are named. It has a type annotation. It is much more self-documenting that way! Testing the logic gets easier too. Nice side benefit!
(<<) :: (b -> c) -> (a -> b) -> a -> c infixl 9 Source #
Function composition, passing results along in the suggested direction. For example, the following code checks if the square root of a number is odd:
not << isEven << sqrt
You can think of this operator as equivalent to the following:
(g << f) == (\x -> g (f x))
So our example expands out to something like this:
\n -> not (isEven (sqrt n))
(>>) :: (a -> b) -> (b -> c) -> a -> c infixr 9 Source #
Function composition, passing results along in the suggested direction. For example, the following code checks if the square root of a number is odd:
sqrt >> isEven >> not
A value that can never happen! For context:
- The boolean type
Bool
has two values:True
andFalse
- The unit type
()
has one value:()
- The never type
Never
has no values!
You may see it in the wild in Html Never
which means this HTML will never
produce any messages. You would need to write an event handler like
onClick ??? :: Attribute Never
but how can we fill in the question marks?!
So there cannot be any event handlers on that HTML.
You may also see this used with tasks that never fail, like Task Never ()
.
The Never
type is useful for restricting *arguments* to a function. Maybe my
API can only accept HTML without event handlers, so I require Html Never
and
users can give Html msg
and everything will go fine. Generally speaking, you
do not want Never
in your return types though.
A function that can never be called. Seems extremely pointless, but it *can* come in handy. Imagine you have some HTML that should never produce any messages. And say you want to use it in some other HTML that *does* produce messages. You could say:
import Html exposing (..) embedHtml :: Html Never -> Html msg embedHtml staticStuff = div [] [ text "hello" , Html.map never staticStuff ]
So the never
function is basically telling the type system, make sure no one
ever calls me!
Often-implemented typeclasses
The Eq
class defines equality (==
) and inequality (/=
).
All the basic datatypes exported by the Prelude are instances of Eq
,
and Eq
may be derived for any datatype whose constituents are also
instances of Eq
.
The Haskell Report defines no laws for Eq
. However, ==
is customarily
expected to implement an equivalence relationship where two values comparing
equal are indistinguishable by "public" functions, with a "public" function
being one not allowing to see implementation details. For example, for a
type representing non-normalised natural numbers modulo 100, a "public"
function doesn't make the difference between 1 and 201. It is expected to
have the following properties:
Instances
The Ord
class is used for totally ordered datatypes.
Instances of Ord
can be derived for any user-defined datatype whose
constituent types are in Ord
. The declared order of the constructors in
the data declaration determines the ordering in derived Ord
instances. The
Ordering
datatype allows a single comparison to determine the precise
ordering of two objects.
The Haskell Report defines no laws for Ord
. However, <=
is customarily
expected to implement a non-strict partial order and have the following
properties:
- Transitivity
- if
x <= y && y <= z
=True
, thenx <= z
=True
- Reflexivity
x <= x
=True
- Antisymmetry
- if
x <= y && y <= x
=True
, thenx == y
=True
Note that the following operator interactions are expected to hold:
x >= y
=y <= x
x < y
=x <= y && x /= y
x > y
=y < x
x < y
=compare x y == LT
x > y
=compare x y == GT
x == y
=compare x y == EQ
min x y == if x <= y then x else y
=True
max x y == if x >= y then x else y
=True
Note that (7.) and (8.) do not require min
and max
to return either of
their arguments. The result is merely required to equal one of the
arguments in terms of (==)
.
Minimal complete definition: either compare
or <=
.
Using compare
can be more efficient for complex types.
Instances
Basic numeric class.
The Haskell Report defines no laws for Num
. However, (
and +
)(
are
customarily expected to define a ring and have the following properties:*
)
- Associativity of
(
+
) (x + y) + z
=x + (y + z)
- Commutativity of
(
+
) x + y
=y + x
is the additive identityfromInteger
0x + fromInteger 0
=x
negate
gives the additive inversex + negate x
=fromInteger 0
- Associativity of
(
*
) (x * y) * z
=x * (y * z)
is the multiplicative identityfromInteger
1x * fromInteger 1
=x
andfromInteger 1 * x
=x
- Distributivity of
(
with respect to*
)(
+
) a * (b + c)
=(a * b) + (a * c)
and(b + c) * a
=(b * a) + (c * a)
Note that it isn't customarily expected that a type instance of both Num
and Ord
implement an ordered ring. Indeed, in base
only Integer
and
Rational
do.