Search code examples
functionhaskellfold

Folding with a passed function in Haskell


I have a function func in haskell of the form func :: (Foldable t, Eq b, Num b) => t b -> b, this is intended to take a function from a pre-existing main function (i.e. I can't change the input/output pattern), which is a helper of the form helper :: (Eq a,Num a) => a -> a -> a, as well as a list of values, and I want to fold the list with the operation given in the helper function.

The full code block is

helper :: (Eq a,Num a) =>  a -> a -> a
helper x y  
  | x == 0 && y == 0 = 0
  | x == 0 && y == 1 = 1
  | x == 1 && y == 0 = 1
  | x == 1 && y == 1 = 0

func :: (Foldable t, Eq b, Num b) => t b -> b
func help lst = foldl (help) 0 lst

Which gives a compilation error:

File.hs:23:23: error:
    • Couldn't match type ‘b’ with ‘a0 -> b0’
      Expected: b0 -> a0 -> b0
        Actual: t b
      ‘b’ is a rigid type variable bound by
        the type signature for:
          func :: forall (t :: * -> *) b.
                 (Foldable t, Eq b, Num b) =>
                 t b -> b
        at File.hs:22:1-44
    • In the first argument of ‘foldl’, namely ‘(help)’
      In the expression: foldl (help) 0 lst
      In an equation for ‘func’: func help lst = foldl (help) 0 lst
    • Relevant bindings include
        lst :: t0 a0 (bound at File.hs:23:10)
        help :: t b (bound at File.hs:23:5)
        func :: t b -> b (bound at File.hs:23:1)

I honestly have no idea how to fix this.


Solution

  • You use the helper function here, not a parameter, so you work with:

    func :: (Foldable t, Eq b, Num b) => t b -> b
    func lst = foldl helper 0 last

    or shorter:

    func :: (Foldable t, Eq b, Num b) => t b -> b
    func = foldl helper 0

    You can also make use of xor :: Bits a => a -> a -> a:

    import Data.Bits(Bits, xor)
    
    func :: (Foldable t, Bits b, Num b) => t b -> b
    func = foldl xor 0