Em Haskell, as funções são entidades de primeira ordem, ou seja, as funções podem receber outras funções como argumento.

twice :: (a -> a) -> a -> a 
twice f x = f (f x)

Exemplos :

dobro :: Int -> Int 
dobro x = x + x

quadruplo :: Int -> Int 
quadruplo x = twice dobro x

quadruplo 5
= twice dobro 5
= dobro (dobro 5)
= (dobro 5) + (dobro 5) = (5+5) + (5+5)
= 10 + 10
= 20
------------------------------------------------------------------------------------
retira2 :: [a] -> [a] 
retira2 l = twice tail l

retira2 [4,5,7,0,9] 
= twice tail [4,5,7,0,9] 
= tail (tail [4,5,7,0,9])
= tail [5,7,0,9] 
= tail [7,0,9]
= [7,0,9]

As funções podem devolver outras funções como resultado.

mult :: Int -> Int -> Int 
mult x y = x * y

O tipo é igual a Int -> **(**Int -> Int**)**, porque -> é associativo à direita

Exemplos :

triplo :: Int -> Int 
triplo = mult 3
-- triplo tem o mesmo tipo que mult 3
triplo 5 
= mult 3 5 =3*5
= 15
-- mult 3 5 = (mult 3) 5, porque a aplicação é associativa à esquerda

twice (mult 2) 5 
= (mult 2) ((mult 2) 5) 
= mult 2 (mult 2 5) 
= 2 * (mult 2 5)
= 2 * (2 * 5) 
= 20

Outras funções :

map

Filter

(.) - composição de funções

Flip

Curry and Uncurry

zipWith

takeWhile, dropWhile and span