Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell Function Composition - (a -> b) -> (a -> c) -> (b -> c -> d) -> (a -> d)

I would like to learn how the following would be done in point-free:

withinBounds :: [Int] -> Bool
withinBounds xs = (all (>= 0) xs) && (all (<= 8) xs)

I understand that it is superior to write it this way for readability/sanity's sake, but I'd like to learn more about how I can compose functions. I've been scratching my head as to how I can do this. The whole (expanded?) type signature is

[Int] -> ([Int] -> Bool) -> ([Int] -> Bool) -> (Bool -> Bool -> Bool) -> Bool

The type signature of the composition I'm trying to get to is

(a -> b) -> (a -> c) -> (b -> c -> d) -> (a -> d)

I wrote the following as notes in a bastard-lambda form. If there is a way to somewhat simplify the problem with the lambda calculus, it'd be great if that could be explained too:

\L@[] ->  \f1@([] -> Bool) -> \f2@([] -> Bool) -> \f3@(Bool -> Bool -> Bool) -> f3.(f1.L).(f2.L) 

In the above, . is application, @ is capturing (so f3 is another name for (Bool -> Bool -> Bool)). Many thanks.

Edit: I know this is not the most optimal or reusable code, and I know turning this into point-free makes it worse in terms of readability etc. To clarify, I am asking how I can turn it into point-free because I want to learn more about haskell and composition.

Edit2: A really good SO answer on point-free

like image 474
MIJOTHY Avatar asked Jul 06 '16 07:07

MIJOTHY


People also ask

What is function composition in Haskell?

Composing functions is a common and useful way to create new functions in Haskell. Haskell composition is based on the idea of function composition in mathematics. In mathematics, if you have two functions f(x) and g(x), you compute their composition as f(g(x)). The expression f(g(x)) first calls g and then calls f.

What does -> mean in Haskell?

(->) is often called the "function arrow" or "function type constructor", and while it does have some special syntax, there's not that much special about it. It's essentially an infix type operator. Give it two types, and it gives you the type of functions between those types.

How do functions work in Haskell?

Functions play a major role in Haskell, as it is a functional programming language. Like other languages, Haskell does have its own functional definition and declaration. Function declaration consists of the function name and its argument list along with its output.

How are higher order functions used in Haskell?

In Haskell, a function that can take other functions as arguments or return functions is called a higher-order function. These are particularly useful in that they allow us to create new functions on top of the ones we already have, by passing functions as arguments to other functions.


1 Answers

You could use the fact that function is Applicative. and write withinBounds this way:

withinBounds = pure (&&) <*> all (>= 0) <*> all (<= 8)

Or this way:

withinBounds = (&&) <$> all (>= 0) <*> all (<= 8)

You could read about Applicatives here and here

like image 155
Safareli Avatar answered Oct 05 '22 04:10

Safareli