type Dollar = Dollar Float priceInEuros: Dollar -> Float priceInEuros (Dollar d) = d * 1.1 priceInEuros 3.3 -- 3.63
Every function that accepts two arguments can be converted in one that accepts one argument:
> String.repeat <function> : Int -> String -> String > String.repeat 4 <function> : String -> String
Then there is this:
double = (*) 2 <function> : number -> number
This can happen because all functions accept only and exactly one argument.
> greeting : String -> String -> String | greeting greet name = greet ++ ", " ++ name ++ "!" <function> : String -> String -> String > greeting "Hello" "DailyDrip" == ((greeting "Hello") "DailyDrip") True : Bool
Parentheses are optional because function evaluation associates to the left by default.
> (*) <function> : number -> number -> number double = (*) 2 <function> : number -> number
As we can see we can think that (*) takes two numbers as arguments. On double function the compiler will really infer that our double function takes one number as its sole argument.
Then we can easily create a function for doubling values on a list:
doubleList = List.map double -- <function> : List number -> List number
This is the main reason why the data structure should be always the last argument.
He have also this:
> (|>)
<function> : a -> (a -> b) -> b
amountDeposited : List Transaction -> Float
amountDeposited list =
List.filter (\t -> t.type_ == Deposit) list
|> List.map .amount
|> List.sum
-- It filters all the transactions in list which are deposits and obtain the amount for, at the last step, sum them.
-- rather than the nested equivalent:
-- List.sum (List.map .amount (List.filter (\t -> t.type_ == Deposit) list))
> type alias MyType = Int -> String -> String > mytrial: MyType | mytrial n s = String.repeat n s <function> : Int -> String -> String > mytrial 3 "abc" "abcabcabc" : String