- Elchemy.XString
- Elchemy.XResult
- Elchemy.XBasics
- Elchemy.XList
- Elchemy.XDebug
- Elchemy.XChar
- Elchemy
- Elchemy.XMaybe
- Elchemy.XTuple
- isEmpty
- length
- reverse
- repeat
- cons
- uncons
- fromChar
- append
- concat
- split
- join
- words
- lines
- slice
- left
- right
- dropLeft
- dropRight
- contains
- startsWith
- endsWith
- indexes
- indices
- toInt
- toFloat
- toList
- fromList
- toUpper
- toLower
- pad
- padLeft
- padRight
- trim
- trimLeft
- trimRight
- map
- filter
- foldl
- foldr
- any
- all
A built-in representation for efficient string manipulation. String literals
are enclosed in "double quotes". Strings are not lists of characters.
isEmpty : String -> BoolDetermine if a string is empty.
isEmpty "" == True
isEmpty "the world" == Falselength : String -> IntGet the length of a string.
length "innumerable" == 11
length "" == 0reverse : String -> StringReverse a string.
reverse "stressed" == "desserts"repeat : Int -> String -> StringRepeat a string n times.
repeat 3 "ha" == "hahaha"cons : Char -> String -> StringAdd a character to the beginning of a string.
XString.cons 'T' "he truth is out there" == "The truth is out there"uncons : String -> Maybe.Maybe ( Char, String )Split a non-empty string into its head and tail. This lets you pattern match on strings exactly as you would with lists.
uncons "abc" == Just ('a',"bc")
uncons "" == NothingfromChar : Char -> StringCreate a string from a given character.
fromChar 'a' == "a"append : String -> String -> StringAppend two strings. You can also use the (++) operator
to do this.
append "butter" "fly" == "butterfly"concat : List String -> StringConcatenate many strings into one.
concat ["never","the","less"] == "nevertheless"split : String -> String -> List StringSplit a string using a given separator.
split "," "cat,dog,cow" == ["cat","dog","cow"]
split "/" "home/evan/Desktop/" == ["home","evan","Desktop", ""]Use Regex.split if you need something more flexible.
join : String -> List String -> StringPut many strings together with a given separator.
join "a" ["H","w","ii","n"] == "Hawaiian"
join " " ["cat","dog","cow"] == "cat dog cow"
join "/" ["home","evan","Desktop"] == "home/evan/Desktop"words : String -> List StringBreak a string into words, splitting on chunks of whitespace.
words "How are \t you? \n Good?" == ["How","are","you?","Good?"]lines : String -> List StringBreak a string into lines, splitting on newlines.
lines "How are you?\nGood?" == ["How are you?", "Good?"]slice : Int -> Int -> String -> StringTake a substring given a start and end index. Negative indexes are taken starting from the end of the list.
slice 7 9 "snakes on a plane!" == "on"
slice 0 6 "snakes on a plane!" == "snakes"
slice 0 -7 "snakes on a plane!" == "snakes on a"
slice -6 -1 "snakes on a plane!" == "plane"left : Int -> String -> StringTake n characters from the left side of a string.
left 2 "Mulder" == "Mu"right : Int -> String -> StringTake n characters from the right side of a string.
right 2 "Scully" == "ly"dropLeft : Int -> String -> StringDrop n characters from the left side of a string.
dropLeft 2 "The Lone Gunmen" == "e Lone Gunmen"dropRight : Int -> String -> StringDrop n characters from the right side of a string.
dropRight 2 "Cigarette Smoking Man" == "Cigarette Smoking M"contains : String -> String -> BoolSee if the second string contains the first one.
contains "the" "theory" == True
contains "hat" "theory" == False
contains "THE" "theory" == FalseUse Regex.contains if you need something more flexible.
startsWith : String -> String -> BoolSee if the second string starts with the first one.
startsWith "the" "theory" == True
startsWith "ory" "theory" == FalseendsWith : String -> String -> BoolSee if the second string ends with the first one.
endsWith "the" "theory" == False
endsWith "ory" "theory" == Trueindexes : String -> String -> List IntGet all of the indexes for a substring in another string.
indexes "i" "Mississippi" == [1,4,7,10]
indexes "ss" "Mississippi" == [2,5]
indexes "needle" "haystack" == []indices : String -> String -> List IntAlias for indexes.
toInt : String -> Result.Result String IntTry to convert a string into an int, failing on improperly formatted strings.
XString.toInt "123" == Ok 123
XString.toInt "-42" == Ok -42
XString.toInt "3.1" == Err "could not convert string '3.1' to an Int"
XString.toInt "31a" == Err "could not convert string '31a' to an Int"If you are extracting a number from some raw user input, you will typically
want to use Result.withDefault to handle bad data:
XResult.withDefault 0 (XString.toInt "42") == 42
XResult.withDefault 0 (XString.toInt "ab") == 0toFloat : String -> Result.Result String FloatTry to convert a string into a float, failing on improperly formatted strings.
XString.toFloat "123" == Ok 123.0
XString.toFloat "-42" == Ok -42.0
XString.toFloat "3.1" == Ok 3.1
XString.toFloat "31a" == Err "could not convert string '31a' to a Float"If you are extracting a number from some raw user input, you will typically
want to use Result.withDefault to handle bad data:
XResult.withDefault 0 (XString.toFloat "42.5") == 42.5
XResult.withDefault 0 (XString.toFloat "cats") == 0toList : String -> List CharConvert a string to a list of characters.
toList "abc" == ['a','b','c']fromList : List Char -> StringConvert a list of characters into a String. Can be useful if you want to create a string primarily by consing, perhaps for decoding something.
fromList ['a','b','c'] == "abc"Cosmetic operations such as padding with extra characters or trimming whitespace.
toUpper : String -> StringConvert a string to all upper case. Useful for case-insensitive comparisons and VIRTUAL YELLING.
toUpper "skinner" == "SKINNER"toLower : String -> StringConvert a string to all lower case. Useful for case-insensitive comparisons.
toLower "X-FILES" == "x-files"pad : Int -> Char -> String -> StringPad a string on both sides until it has a given length.
pad 5 ' ' "1" == " 1 "
pad 5 ' ' "11" == " 11 "
pad 5 ' ' "121" == " 121 "padLeft : Int -> Char -> String -> StringPad a string on the left until it has a given length.
padLeft 5 '.' "1" == "....1"
padLeft 5 '.' "11" == "...11"
padLeft 5 '.' "121" == "..121"padRight : Int -> Char -> String -> StringPad a string on the right until it has a given length.
padRight 5 '.' "1" == "1...."
padRight 5 '.' "11" == "11..."
padRight 5 '.' "121" == "121.."trim : String -> StringGet rid of whitespace on both sides of a string.
trim " hats \n" == "hats"trimLeft : String -> StringGet rid of whitespace on the left of a string.
trimLeft " hats \n" == "hats \n"trimRight : String -> StringGet rid of whitespace on the right of a string.
trimRight " hats \n" == " hats"map : (Char -> Char) -> String -> StringTransform every character in a string
map (\c -> if c == '/' then '.' else c) "a/b/c" == "a.b.c"filter : (Char -> Bool) -> String -> StringKeep only the characters that satisfy the predicate.
filter ((==) '2') "R2-D2" == "22"foldl : (Char -> b -> b) -> b -> String -> bReduce a string from the left.
foldl XString.cons "" "time" == "emit"foldr : (Char -> b -> b) -> b -> String -> bReduce a string from the right.
foldr XString.cons "" "time" == "time"any : (Char -> Bool) -> String -> BoolDetermine whether any characters satisfy a predicate.
any XChar.isDigit "90210" == True
any XChar.isDigit "R2-D2" == True
any XChar.isDigit "heart" == Falseall : (Char -> Bool) -> String -> BoolDetermine whether all characters satisfy a predicate.
all XChar.isDigit "90210" == True
all XChar.isDigit "R2-D2" == False
all XChar.isDigit "heart" == FalseA Result is the result of a computation that may fail. This is a great
way to manage errors in Elm.
type Result error value
= Ok value
| Err errorA Result is either Ok meaning the computation succeeded, or it is an
Err meaning that there was some failure.
map : (a -> value) -> Result x a -> Result x valueApply a function to a result. If the result is Ok, it will be converted.
If the result is an Err, the same error value will propagate through.
map sqrt (Ok 4.0) == Ok 2.0
map sqrt (Err "bad input") == Err "bad input"map2 : (a -> b -> value) -> Result x a -> Result x b -> Result x valueApply a function to two results, if both results are Ok. If not,
the first argument which is an Err will propagate through.
map2 (+) (XString.toInt "1") (XString.toInt "2") == Ok 3
map2 (+) (XString.toInt "1") (XString.toInt "y") == Err "could not convert string 'y' to an Int"
map2 (+) (XString.toInt "x") (XString.toInt "y") == Err "could not convert string 'x' to an Int"map3 : (a -> b -> c -> value) -> Result x a -> Result x b -> Result x c -> Result x valuemap4 : (a -> b -> c -> d -> value) -> Result x a -> Result x b -> Result x c -> Result x d -> Result x valuemap5 : (a -> b -> c -> d -> e -> value) -> Result x a -> Result x b -> Result x c -> Result x d -> Result x e -> Result x valueandThen : (a -> Result x b) -> Result x a -> Result x bChain together a sequence of computations that may fail. It is helpful to see its definition:
This means we only continue with the callback if things are going well. For
example, say you need to use (toInt : String -> Result String Int) to parse
a month and make sure it is between 1 and 12:
This allows us to come out of a chain of operations with quite a specific error message. It is often best to create a custom type that explicitly represents the exact ways your computation may fail. This way it is easy to handle in your code.
withDefault : a -> Result x a -> aIf the result is Ok return the value, but if the result is an Err then
return a given default value. The following examples try to parse integers.
withDefault 0 (XString.toInt "123") == 123
withDefault 0 (XString.toInt "abc") == 0toMaybe : Result x a -> Maybe.Maybe aConvert to a simpler Maybe if the actual error message is not needed or
you need to interact with some code that primarily uses maybes.
fromMaybe : x -> Maybe.Maybe a -> Result x aConvert from a simple Maybe to interact with some code that primarily
uses Results.
mapError : (x -> y) -> Result x a -> Result y aTransform an Err value. For example, say the errors we get have too much
information:
mapError XTuple.first (Ok (123, 1)) == Ok (123, 1)
mapError XTuple.second (Err ("nothing", "important")) == Err "important"- compare
- xor
- sqrt
- clamp
- compare
- xor
- negate
- sqrt
- logBase
- e
- pi
- cos
- sin
- tan
- acos
- asin
- atan
- atan2
- round
- floor
- ceiling
- truncate
- toFloat
- toString
- ++
- identity
- always
- flip
- tuple2
- tuple3
- tuple4
- tuple5
- Order
Tons of useful functions that get imported by default.
compare : comparable -> comparable -> OrderBasic compare function
compare 1 2 == LTxor : Bool -> Bool -> BoolThe exclusive-or operator. True if exactly one input is True.
sqrt : number -> FloatTake the square root of a number.
clamp : comparable -> comparable -> comparable -> comparableClamps 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 -> OrderBasic compare function
compare 1 2 == LTxor : Bool -> Bool -> BoolThe exclusive-or operator. True if exactly one input is True.
negate : number -> numberNegate a number.
negate 42 == -42
negate -42 == 42
negate 0 == 0sqrt : number -> FloatTake the square root of a number.
logBase : Float -> Float -> Floate : Floatpi : Floatcos : Float -> Floatsin : Float -> Floattan : Float -> Floatacos : Float -> Floatasin : Float -> Floatatan : Float -> Floatatan2 : Float -> Float -> Floatround : Float -> Intfloor : Float -> Intceiling : Float -> Inttruncate : Float -> IntTruncate a number, rounding towards zero.
toFloat : Int -> FloatConvert an integer into a float.
toString : a -> StringTurn 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]"++ : appendable -> appendable -> appendablePut 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]identity : a -> aGiven a value, returns exactly the same value. This is called the identity function.
always : a -> a -> aCreate 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 -> cFlip 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.
- isEmpty
- length
- reverse
- member
- head
- tail
- filter
- take
- drop
- singleton
- repeat
- range
- cons
- ::
- append
- concat
- intersperse
- partition
- unzip
- map
- map2
- filterMap
- concatMap
- indexedMap
- foldr
- foldl
- sum
- product
- maximum
- minimum
- all
- any
- scanl
- sort
- sortBy
- sortWith
A library for manipulating lists of values. Every value in a list must have the same type.
isEmpty : List a -> BoolDetermine if a list is empty.
isEmpty [] == Truelength : List a -> IntDetermine the length of a list.
length [1,2,3] == 3reverse : List a -> List aReverse a list.
reverse [1,2,3,4] == [4,3,2,1]member : a -> List a -> BoolFigure out whether a list contains a value.
member 9 [1,2,3,4] == False
member 4 [1,2,3,4] == Truehead : List a -> Maybe.Maybe aExtract the first element of a list.
head [1,2,3] == Just 1
head [] == Nothingtail : List a -> Maybe.Maybe (List a)Extract the rest of the list.
tail [1,2,3] == Just [2,3]
tail [] == Nothingfilter : (a -> Bool) -> List a -> List aKeep only elements that satisfy the predicate.
filter (flip (%) 2 >> (==) 0) [1,2,3,4,5,6] == [2,4,6]take : Int -> List a -> List aTake the first n members of a list.
take 2 [1,2,3,4] == [1,2]drop : Int -> List a -> List aDrop the first n members of a list.
drop 2 [1,2,3,4] == [3,4]singleton : a -> List aCreate a list with only one element:
singleton 1234 == [1234]
singleton "hi" == ["hi"]repeat : Int -> a -> List aCreate a list with n copies of a value:
repeat 3 0 == [0, 0, 0]range : Int -> Int -> List IntCreate a list of numbers, every element increasing by one. You give the lowest and highest number that should be in the list.
range 3 6 == [3, 4, 5, 6]
range 3 3 == [3]
range 6 3 == []cons : a -> List a -> List aAdd an element to the front of a list. Pronounced cons.
cons 1 [2,3] == [1,2,3]
cons 1 [] == [1]:: : a -> List a -> List aAdd an element to the front of a list. Pronounced cons.
1 :: [2,3] == [1,2,3]
1 :: [] == [1]append : List a -> List a -> List aPut two lists together.
append [1,1,2] [3,5,8] == [1,1,2,3,5,8]
append ['a','b'] ['c'] == ['a','b','c']You can also use the (++) operator to append lists.
concat : List (List a) -> List aConcatenate a bunch of lists into a single list:
concat [[1,2],[3],[4,5]] == [1,2,3,4,5]intersperse : a -> List a -> List aPlaces the given value between all members of the given list.
intersperse "on" ["turtles","turtles","turtles"] == ["turtles","on","turtles","on","turtles"]partition : (a -> Bool) -> List a -> ( List a, List a )Partition a list based on a predicate. The first list contains all values that satisfy the predicate, and the second list contains all the value that do not.
partition (\x -> x < 3) [0,1,2,3,4,5] == ([0,1,2], [3,4,5])
partition (\a -> a % 2 == 0) [0,1,2,3,4,5] == ([0,2,4], [1,3,5])unzip : List ( a, b ) -> ( List a, List b )Decompose a list of tuples into a tuple of lists.
unzip (repeat 3 (0, True)) == ([0,0,0], [True,True,True])map : (a -> b) -> List a -> List bApply a function to every element of a list.
map sqrt [1,4,9] == [1.0,2.0,3.0]
map not [True,False,True] == [False,True,False]map2 : (a -> b -> result) -> List a -> List b -> List resultCombine two lists, combining them with the given function. If one list is longer, the extra elements are dropped.
map2 (+) [1,2,3] [1,2,3,4] == [2,4,6]
map2 (,) [1,2,3] ['a','b'] == [ (1,'a'), (2,'b') ]If you can think of a legitimate use of mapN where N is 6 or more, please
let us know on the list.
The current sentiment is that it is already quite error prone once you get to
4 and possibly should be approached another way.
filterMap : (a -> Maybe.Maybe b) -> List a -> List bApply a function that may succeed to all values in the list, but only keep the successes.
filterMap (\a -> if a >= 18 then Just a else Nothing) [3, 15, 12, 18, 24] == [18, 24]concatMap : (a -> List b) -> List a -> List bMap a given function onto a list and flatten the resulting lists.
concatMap (range 2) [1] == concat (map (range 2) [1]) == TrueindexedMap : (Int -> a -> b) -> List a -> List bSame as map but the function is also applied to the index of each
element (starting at zero).
indexedMap (,) ["Tom","Sue","Bob"] == [ (0,"Tom"), (1,"Sue"), (2,"Bob") ]foldr : (a -> b -> b) -> b -> List a -> bReduce a list from the right.
foldr (+) 0 [1,2,3] == 6foldl : (a -> b -> b) -> b -> List a -> bReduce a list from the left.
foldl (::) [] [1,2,3] == [3,2,1]sum : List number -> numberGet the sum of the list elements.
sum [1,2,3,4] == 10product : List number -> numberGet the product of the list elements.
product [1,2,3,4] == 24maximum : List comparable -> Maybe.Maybe comparableFind the maximum element in a non-empty list.
maximum [1,4,2] == Just 4
maximum [] == Nothingminimum : List comparable -> Maybe.Maybe comparableFind the minimum element in a non-empty list.
minimum [3,2,1] == Just 1
minimum [] == Nothingall : (a -> Bool) -> List a -> BoolDetermine if all elements satisfy the predicate.
all (\a -> a % 2 == 0) [2,4] == True
all (\a -> a % 2 == 0) [2,3] == False
all (\a -> a % 2 == 0) [] == Trueany : (a -> Bool) -> List a -> BoolDetermine if any elements satisfy the predicate.
any (\a -> a % 2 == 0) [2,3] == True
any (\a -> a % 2 == 0) [1,3] == False
any (\a -> a % 2 == 0) [] == Falsescanl : (a -> b -> b) -> b -> List a -> List bReduce a list from the left, building up all of the intermediate results into a list.
scanl (+) 0 [1,2,3,4] == [0,1,3,6,10]sort : List comparable -> List comparableSort values from lowest to highest
sort [3,1,5] == [1,3,5]sortBy : (a -> comparable) -> List a -> List aSort values by a derived property. To be replaced
sortBy (\(i, _) -> i) [(1, "mouse"),(0, "cat")] == [(0, "cat"), (1, "mouse")]sortWith : (a -> a -> Basics.Order) -> List a -> List aSort values with a custom comparison function.
sortWith (flip compare) [1,2,3,4,5] == [5,4,3,2,1]This is also the most general sort function, allowing you
to define any other: sort == sortWith compare
f
Module with helper functions for debugging
log : String -> a -> aLog to console in title: object format
crash : String -> aRaise an exception to crash the runtime. Should be avoided at all costs. Helpful for crashing at not yet implelented functionality
Functions for working with characters. Character literals are enclosed in
'a' pair of single quotes.
isUpper : Char -> BoolTrue for upper case ASCII letters.
isUpper 'D' == True
isUpper 'A' == True
isUpper 'x' == FalseisLower : Char -> BoolTrue for lower case ASCII letters.
isLower 'd' == True
isLower 'a' == True
isLower 'X' == FalseisDigit : Char -> BoolTrue for ASCII digits [0-9].
isDigit '1' == True
isDigit '9' == True
isDigit 'a' == FalseisOctDigit : Char -> BoolTrue for ASCII octal digits [0-7].
isOctDigit '7' == True
isOctDigit '5' == True
isOctDigit '9' == FalseisHexDigit : Char -> BoolTrue for ASCII hexadecimal digits [0-9a-fA-F].
isHexDigit 'd' == True
isHexDigit 'D' == True
isHexDigit 'x' == FalsetoUpper : Char -> CharConvert to upper case.
toUpper 'a' == 'A'toLower : Char -> CharConvert to lower case.
toLower 'A' == 'a'type alias KeyCode =
IntKeyboard keys can be represented as integers. These are called key codes.
You can use toCode and fromCode to convert between
key codes and characters.
toCode : Char -> KeyCodeConvert to key code.
toCode 'a' == 97fromCode : KeyCode -> CharConvert from key code.
fromCode 97 == 'a'Module to help express some Elixir related types and calls that wouldn't otherwise be possible
lffi : String -> aDeprecated since Elchemy 0.3.0 Function to make a direct Elixir local call. Takes a local function name and a tuple or single value of arguments
lffi "to_string"ffi : String -> String -> aFunction to make a direct Elixir remote call. Takes a module name and a function name Ffi functions must be the only call in the entire function and the type declaration is mandatory. For example
mySum : List number -> number
mySum =
ffi "Enum" "sum"That function will call Enum.sum(list) on our parameter, and also it will generate
a type verification macro, that makes sure, that Enum.sum/1 actually returns
our type (List number -> number).
To actiate the typecheck put
typetest MyModuleinside of your test suite
tryFfi : String -> String -> aFunction to make a direct Elixir remote call. Takes a module name, a function name and a tuple or single value of arguments. tryFfi verifies no types at compile time but it makes sure the value you're requesting is what you're expecting wrappend in Result.Ok Type, or otherwise you get a Result.Error String
myToFloat : String -> Result Float
myToFloat =
ffi "Kernel" "to_float"flambda : Int -> a -> bDeprecated since Elchemy 0.3.0
Produce multiple argument anonymous function out of regular elm function.
flambda 2 fun --> fn x1, x2 -> fun.(x1).(x2) endtryCatch : (() -> a) -> Result.Result String aDeprecated since Elchemy 0.3.0
Wrap a function call in try catch returning Result based on wether the function throwed an error
This library fills a bunch of important niches in Elm. A Maybe can help
you with optional arguments, error handling, and records with optional fields.
type Maybe a
= Just a
| Nothing Represent values that may or may not exist. It can be useful if you have a record field that is only filled in sometimes. Or if a function takes a value sometimes, but does not absolutely need it.
withDefault : a -> Maybe a -> aProvide a default value, turning an optional value into a normal
value. This comes in handy when paired with functions like
Dict.get which gives back a Maybe.
withDefault 100 (Just 42) == 42
withDefault 100 Nothing == 100map : (a -> b) -> Maybe a -> Maybe bTransform a Maybe value with a given function:
map ((+) 2) (Just 9) == Just 11
map ((+) 2) Nothing == Nothingmap2 : (a -> b -> value) -> Maybe a -> Maybe b -> Maybe valueApply a function if all the arguments are Just a value.
map2 (+) (Just 3) (Just 4) == Just 7
map2 (+) (Just 3) Nothing == Nothing
map2 (+) Nothing (Just 4) == Nothingmap3 : (a -> b -> c -> value) -> Maybe a -> Maybe b -> Maybe c -> Maybe valuemap4 : (a -> b -> c -> d -> value) -> Maybe a -> Maybe b -> Maybe c -> Maybe d -> Maybe valuemap5 : (a -> b -> c -> d -> e -> value) -> Maybe a -> Maybe b -> Maybe c -> Maybe d -> Maybe e -> Maybe valueandThen : (a -> Maybe b) -> Maybe a -> Maybe bChain together many computations that may fail. It is helpful to see its definition:
This means we only continue with the callback if things are going well. For
example, say you need to use (head : List Int -> Maybe Int) to get the
first month from a List and then make sure it is between 1 and 12:
If head fails and results in Nothing (because the List was empty),
this entire chain of operations will short-circuit and result in Nothing.
If toValidMonth results in Nothing, again the chain of computations
will result in Nothing.
Module for tuple manipulation
first : ( a, b ) -> aExtract the first value from a tuple.
first (3, 4) == 3
first ("john", "doe") == "john"second : ( a, b ) -> bExtract the second value from a tuple.
second (3, 4) == 4
second ("john", "doe") == "doe"mapFirst : (a -> a1) -> ( a, b ) -> ( a1, b )Transform the first value in a tuple.
mapFirst String.reverse ("stressed", 16) == ("desserts", 16)
mapFirst String.length ("stressed", 16) == (8, 16)mapSecond : (b -> b1) -> ( a, b ) -> ( a, b1 )Transform the second value in a tuple.
mapSecond sqrt ("stressed", 16) == ("stressed", 4.0)
mapSecond (\x -> x + 1) ("stressed", 16) == ("stressed", 17)Generated with elm-make: 0.18.0 and elm-docs: 0.1.0