Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Seemingly legal Eta reduction causing issues

I am attempting to η-reduce the function

foldr :: (a -> b -> b) -> b -> BinaryTree a -> b
foldr combiner base tree = foldMap combiner tree base where
  foldMap = ...

with

foldMap :: (a -> b -> b) -> BinaryTree a -> b -> b

working as intended.

I have η-reduced

foldr combiner base tree = foldMap combiner tree base

to

foldr combiner = flip $ foldMap combiner where
  ...

This works as intended. It seems like I should be able to η-reduce completely to get the pointfree function

foldr = flip $ foldMap where
  ...

However, this causes a compilation error

Couldn't match type ‘a -> b -> b’ with ‘BinaryTree t0’
Expected type: (a -> b -> b) -> b -> BinaryTree a -> b
  Actual type: BinaryTree t0 -> (t0 -> b -> b) -> b -> b

Is it possible to η-reduce farther, and if so, how?

like image 347
Sam Craig Avatar asked Oct 04 '18 17:10

Sam Craig


1 Answers

The error is raised, because g b = f $ a b is not equivalent to g = f $ a.

In the first case you get the following sequence of evaluation:

  • apply the function a to b (call a with b as an argument)
  • apply the function f to the result

In the second case:

  • apply the function f to a

Thus, you just flip the foldMap function, but actually want to flip the foldMap function after passing combiner to it. This leads us to the conclusion, that you actually want the composition, i. e. . function:

foldr = flip . foldMap where
  ...
like image 111
Igor Drozdov Avatar answered Oct 13 '22 01:10

Igor Drozdov