This is an alternative site for discovering Elm packages. You may be looking for the official Elm package site instead.

# Elchemy.XBasics

Tons of useful functions that get imported by default.

cons : a -> List a -> List a

Add an element to the front of a list. Pronounced cons.

``````cons 1 [2,3] == [1,2,3]
cons 1 [] == 
``````
compare : comparable -> comparable -> Order

Basic compare function

### Example

``````compare 1 2 == LT
``````
xor : Bool -> Bool -> Bool

The exclusive-or operator. `True` if exactly one input is `True`.

sqrt : number -> Float

Take the square root of a number.

clamp : comparable -> comparable -> comparable -> comparable

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

compare : comparable -> comparable -> Order

Basic compare function

### Example

``````compare 1 2 == LT
``````
xor : Bool -> Bool -> Bool

The exclusive-or operator. `True` if exactly one input is `True`.

negate : number -> number

Negate a number.

``````negate 42 == -42
negate -42 == 42
negate 0 == 0
``````
sqrt : number -> Float

Take the square root of a number.

logBase : Float -> Float -> Float
e : 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
round : Float -> Int
floor : Float -> Int
ceiling : Float -> Int
truncate : Float -> Int

Truncate a number, rounding towards zero.

toFloat : Int -> Float

Convert an integer into a float.

isInfinite : Float -> Bool

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`.
``````
isNaN : Float -> Bool

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
``````
toString : a -> String

Turn any kind of value into a string. When you view the resulting string with `Text.fromString` it should look just like the value it came from.

``````toString 42 == "42"
toString [1,2] == "[1, 2]"
``````
identity : a -> a

Given a value, returns exactly the same value. This is called the identity function.

always : a -> a -> a

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]
``````
flip : (a -> b -> c) -> b -> a -> c

Flip the order of the first two arguments to a function.

tuple2 : a -> b -> ( a, b )
tuple3 : a -> b -> c -> ( a, b, c )
tuple4 : a -> b -> c -> d -> ( a, b, c, d )
tuple5 : a -> b -> c -> d -> e -> ( a, b, c, d, e )
type Order = LT | EQ | GT

Represents the relative ordering of two things. The relations are less than, equal to, and greater than.

``````module Elchemy.XBasics
exposing
( cons
, Order(..)
, compare
, xor
, negate
, sqrt
, clamp
, logBase
, e
, pi
, cos
, sin
, tan
, acos
, asin
, atan
, atan2
, round
, floor
, ceiling
, truncate
, toFloat
, isInfinite
, isNaN
, toString
, (++)
, identity
, always
, flip
, tuple2
, tuple3
, tuple4
, tuple5
)

{-| Tons of useful functions that get imported by default.
@docs cons, compare, xor, sqrt, clamp, compare , xor , negate , sqrt , logBase , e , pi , cos , sin , tan , acos , asin , atan , atan2 , round , floor , ceiling , truncate , toFloat , isInfinite, isNaN , toString , (++) , identity , always, flip, tuple2, tuple3, tuple4, tuple5

@docs Order

-}

import Elchemy exposing (..)

{-| Represents the relative ordering of two things.
The relations are less than, equal to, and greater than.
-}
type Order
= LT
| EQ
| GT

-- Operators
{- ex

import Kernel, except: [
{:'++', 2},
{:round, 1},
{:to_string, 1},
{:'|>', 2},
{:floor, 1}
]

curry ==/2
curry !=/2
curry </2
curry >/2
curry <=/2
curry >=/2
curry max/2
curry min/2

curry &&/2
curry ||/2

curry +/2
curry -/2
curry */2
curry abs/1
curry rem/2
# Inlined from not
curry !/1

curry //2
def 0 / 0, do: :nan
def _ / 0, do: :infinity
def l / r, do: Kernel./(l, r)

curry div/2
def div(_, 0), do: 0
def div(l, r), do: Kernel.div(l, r)

@spec infinite?(number() | :infinity) :: boolean()
def infinite?(:infinity), do: true
def infinite?(_), do: false

@spec nan?(float() | :infinity) :: boolean()
def nan?(:nan), do: true
def nan?(_), do: false

def do_sqrt(x) when x < 0, do: :nan
def do_sqrt(x), do: :math.sqrt(x)
-}

{-| Basic compare function

### Example

compare 1 2 == LT

-}
compare : comparable -> comparable -> Order
compare a b =
if a > b then
GT
else if a < b then
LT
else
EQ

{- ex
# >> is replaced with >>> by the compiler
def l >>> r, do: fn x -> r.(l.(x)) end

curry |>/2
defp l |> r, do: r.(l)
-}
-- not/1 is inlined by the compiler

{-| Add an element to the front of a list. Pronounced *cons*.

cons 1 [2,3] == [1,2,3]
cons 1 [] == 

-}
cons : a -> List a -> List a
cons a list =
a :: list

{-| The exclusive-or operator. `True` if exactly one input is `True`.
-}
xor : Bool -> Bool -> Bool
xor a b =
(a && not b) || (not a && b)

{-| Negate a number.

negate 42 == -42
negate -42 == 42
negate 0 == 0

-}
negate : number -> number
negate =
ffi "Kernel" "-"

{- flag noverify:+sqrt -}

{-| Take the square root of a number.
-}
sqrt : number -> Float
sqrt =
ffi "Elchemy.XBasics" "do_sqrt"

{-| 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
-}
clamp : comparable -> comparable -> comparable -> comparable
clamp x bottom top =
x
|> min bottom
|> max top

{-| -}
logBase : Float -> Float -> Float
logBase _ _ =
notImplemented

{-| -}
e : Float
e =
2.71828

{-| -}
pi : Float
pi =
ffi ":math" "pi"

{-| -}
cos : Float -> Float
cos =
ffi ":math" "cos"

{-| -}
sin : Float -> Float
sin =
ffi ":math" "sin"

{-| -}
tan : Float -> Float
tan =
ffi ":math" "tan"

{-| -}
acos : Float -> Float
acos =
ffi ":math" "acos"

{-| -}
asin : Float -> Float
asin =
ffi ":math" "asin"

{-| -}
atan : Float -> Float
atan =
ffi ":math" "atan"

{-| -}
atan2 : Float -> Float -> Float
atan2 =
ffi ":math" "atan2"

{-| -}
round : Float -> Int
round =
ffi "Kernel" "round"

{- flag noverify:+floor -}

{-| -}
floor : Float -> Int
floor x =
ffi "Float" "floor"

{- flag noverify:+ceiling -}

{-| -}
ceiling : Float -> Int
ceiling x =
ffi "Float" "ceil"

{-| Truncate a number, rounding towards zero.
-}
truncate : Float -> Int
truncate _ =
notImplemented

{-| Convert an integer into a float.
-}
toFloat : Int -> Float
toFloat x =
mul_ x 1.0

{- flag noverify:+isInfinite -}

{-| 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`.

-}
isInfinite : Float -> Bool
isInfinite =
ffi "Elchemy.XBasics" "infinite?"

{- flag noverify:+isNaN -}

{-| 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](http://en.wikipedia.org/wiki/NaN).

isNaN (0/0) == True
isNaN (sqrt -1) == True
isNaN (1/0) == False -- infinity is a number
isNaN 1 == False

-}
isNaN : Float -> Bool
isNaN =
ffi "Elchemy.XBasics" "nan?"

mul_ : Int -> Float -> Float
mul_ =
ffi "Kernel" "*"

{-| Turn any kind of value into a string. When you view the resulting string
with `Text.fromString` it should look just like the value it came from.

toString 42 == "42"
toString [1,2] == "[1, 2]"

-}
toString : a -> String
toString a =
inspect_ a []

type BinariesAs
= AsBinaries
| AsStrings

type InspectOption
= Structs Bool
| Binaries BinariesAs

inspect_ : a -> List InspectOption -> String
inspect_ =
ffi "Kernel" "inspect"

{-| 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]

-}
(++) : appendable -> appendable -> appendable
(++) a b =
if isBinary_ a && isBinary_ b then
addStrings_ a b
else
addLists_ a b

isBinary_ : a -> Bool
isBinary_ =
ffi "Kernel" "is_binary"

{- flag noverify:+addStrings_ -}

addStrings_ : appendable -> appendable -> appendable
addStrings_ =
ffi "Kernel" "<>"

{- flag noverify:+addLists_ -}

addLists_ : appendable -> appendable -> appendable
addLists_ =
ffi "Kernel" "++"

{-| Given a value, returns exactly the same value. This is called
[the identity function](http://en.wikipedia.org/wiki/Identity_function).
-}
identity : a -> a
identity a =
a

{-| 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 : a -> a -> a
always a _ =
a

{-| Flip the order of the first two arguments to a function.
-}
flip : (a -> b -> c) -> b -> a -> c
flip f a b =
f b a

-- TODO Will be fixed with #34
{- ex
@spec curried(({any, any} -> any)) :: ((any -> any) -> any)
curry curried/1
def curried(fun) do
fn fst -> fn snd -> fun.({fst, snd}) end end
end

@spec uncurried(((any -> any) -> any)) :: ({any, any} -> any)
curry uncurried/1
def uncurried(fun) do
fn {fst, snd} -> fun.(fst).(snd) end
end

-}
-- We don't care for Never type
-- Additional

notImplemented : a
notImplemented =
let
_ =
throw_ "Not implemented"
in
Debug.crash "a"

throw_ : String -> ()
throw_ =
ffi "Kernel" "throw"

{-| -}
tuple2 : a -> b -> ( a, b )
tuple2 a b =
( a, b )

{-| -}
tuple3 : a -> b -> c -> ( a, b, c )
tuple3 a b c =
( a, b, c )

{-| -}
tuple4 : a -> b -> c -> d -> ( a, b, c, d )
tuple4 a b c d =
( a, b, c, d )

{-| -}
tuple5 : a -> b -> c -> d -> e -> ( a, b, c, d, e )
tuple5 a b c d e =
( a, b, c, d, e )
```
```