Lecture 12-2
Function Types
Functions also have types in the type system. The type of a function is based on the values it takes as an argument and returns.
Single Argument Functions
For a one argument function, the type is written as:
[input type] -> [output type]
Multi-Argument Functions
For a function with more than one argument, the type uses multiple ->
:
[input type] -> [input type] -> [output type]
This makes sense as a Haskell function can only return a single type.
Partial Application
In most functional languages, function can be partially applied. This means that you call a function with fewer arguments than are required.
plus a b = a + b
plus2 = plus 2
> plus2 10
> 12
> plus2 1
> 3
As you can see currying a function is the same as applying a permanent input to a function and leaving the other one open. This means that:
f = plus 1
is the same as:
f x = plus 1 x
In partial application:
- We fix some of the arguments.
- We leave other arguments unfixed.
This creates a new function that only has the unfixed arguments.
Partial Application Types
As the function made in a partial application just a function that takes the unfixed arguments, the inputs are the types of the unfixed arguments. For the functions:
func a b c = a + b + c
func2 = func 23
The type would be func2 :: Int -> Int -> Int
, as the unused arguments are carried over.
Argument Order
The order of the partial application must follow the same order as the original function. This means that is makes more sense to use it on prefix functions:
f = (:) 1
This would allow you to cons 1
onto another list.
Partially Applying Infix Operators
To partially apply an infix operator see the following example:
f = (/2)
This will take a single input and divide it by two. As you can see the infix operator should be put in brackets.
Bracketing for Function Types
Function application should be thought of multiple partial applications.
((multThree x y z = x) * y) * z
This means that the function type brackets to the right:
Int -> Int -> Int -> Int
is the same as:
Int -> (Int -> (Int -> Int))
This is a first look at a higher order function. This means that we are writing one argument functions that return other functions.
Multiple Arguments v.s. Tuples
Previously we’ve seen that you can write function in two ways:
- Using usual “spaces” syntax.
- Using tuples.
multThree x y z = x * y * z
multThree' (x, y, z) = x * y * z
These both do the same thing, but the second version cannot be partially applied. This means is is best to avoid tuples unless they are necessary.
Exercises
isA :: Char -> Bool
isADouble :: Char -> Char -> (Bool, Bool)
exclaim :: [Char] -> [Char]