haskell

Is there a way to express a "function of any kind" in Haskell's type signature?


My newbie's attempt to express the behavior of operator || from C/C++ in Haskell:

orElse :: Bool -> (a -> Bool) -> (a -> Bool)
orElse True _ = const True
orElse False pred = pred

Can this be generalized so that it can accept a -> b -> Bool, a -> b -> c -> Bool and so on as its 2nd argument?

Looked at overloading techniques, HKTs et. al. - nothing seems to deal with generalization by kind...

Edit: I now understand why this was a bad example (reading the definition of operator|| in prelude helped) but am still wondering at the larger question as posed.


Solution

  • You can probably craft your wanted function using type classes, but I'm not sure this is a great idea.

    class MagicOr a where
      magicOr :: a -> a -> a 
    
    instance MagicOr Bool where
      magicOr = (||)
    
    instance MagicOr b => MagicOr (a -> b) where
      magicOr f g = \x -> f x `magicOr` g x
      -- or, alternatively,
      -- magicOr = liftA2 magicOr
    

    The code above defines a magicOr function that can be used on two arguments of type Bool, or of type a -> Bool, or of type a -> b -> Bool, and so on.

    So far, I guess this code is not too bad, and fairly usable.

    Still, depending on what you actually need to do, you might end up building a complex type class machinery, which might be somewhat fragile to use. An example is printf. Its definition is rather tricky since it has to handle an unknown number of parameters. Further, if used wrong, it can confuse the type checker which will spew error messages which are hard to understand.

    Feel free to experiment, of course, and see by yourself. Just be warned that type classes, when abused too much, sometimes lead to unwieldy code.