Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Weeding duplicates from a list of functions

Is it possible to remove the duplicates (as in nub) from a list of functions in Haskell? Basically, is it possible to add an instance for (Eq (Integer -> Integer))

In ghci:

let fs = [(+2), (*2), (^2)]
let cs = concat $ map subsequences $ permutations fs
nub cs

<interactive>:31:1:
No instance for (Eq (Integer -> Integer))
  arising from a use of `nub'
Possible fix:
  add an instance declaration for (Eq (Integer -> Integer))
In the expression: nub cs
In an equation for `it': it = nub cs

Thanks in advance.

...

Further, based on larsmans' answer, I am now able to do this

> let fs = [AddTwo, Double, Square]
> let css = nub $ concat $ map subsequences $ permutations fs

in order to get this

> css

[[],[AddTwo],[Double],[AddTwo,Double],[Square],[AddTwo,Square],[Double,Square],[AddTwo,Double,Square],[Double,AddTwo],[Double,AddTwo,Square],[Square,Double],[Square,AddTwo],[Square,Double,AddTwo],[Double,Square,AddTwo],[Square,AddTwo,Double],[AddTwo,Square,Double]]

and then this

> map (\cs-> call <$> cs <*> [3,4]) css

[[],[5,6],[6,8],[5,6,6,8],[9,16],[5,6,9,16],[6,8,9,16],[5,6,6,8,9,16],[6,8,5,6],[6,8,5,6,9,16],[9,16,6,8],[9,16,5,6],[9,16,6,8,5,6],[6,8,9,16,5,6],[9,16,5,6,6,8],[5,6,9,16,6,8]]

, which was my original intent.

like image 617
Longshanks Avatar asked Dec 03 '25 16:12

Longshanks


1 Answers

No, this is not possible. Functions cannot be compared for equality.

The reason for this is:

  1. Pointer comparison makes very little sense for Haskell functions, since then the equality of id and \x -> id x would change based on whether the latter form is optimized into id.
  2. Extensional comparison of functions is impossible, since it would require a positive solution to the halting problem (both functions having the same halting behavior is a necessary requirement for equality).

The workaround is to represent functions as data:

data Function = AddTwo | Double | Square deriving Eq

call AddTwo  =  (+2)
call Double  =  (*2)
call Square  =  (^2)
like image 105
Fred Foo Avatar answered Dec 06 '25 09:12

Fred Foo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!