It's certainly true that this isn't well typed (not to mention not valid Haskell, since the . is used for namespacing, not access to member variables), but there's no reason that one couldn't do something conceptually similar:
class Boolable a where
toBool :: a -> Bool
(&&) :: a -> a -> a
(||) :: a -> a -> a
a && b = if (toBool a) then b else a
a || b = if (toBool a) then a else b
instance Boolable Int where
toBool 0 = False
toBool _ = True
I don't know how idiomatic this is, but it works. One can see that it really is short-circuiting:
> :l Boolable
[1 of 1] Compiling Main ( Boolable.hs, interpreted )
Ok, modules loaded: Main.
> 1 Main.|| undefined :: Int
1
> 1 Main.&& undefined :: Int
*** Exception: Prelude.undefined
I don't know Haskell well enough to know why the `:: Int` on the end is needed, but I'm sure that that, too, can be worked around.
It's certainly true that this isn't well typed (not to mention not valid Haskell, since the . is used for namespacing, not access to member variables), but there's no reason that one couldn't do something conceptually similar:
I don't know how idiomatic this is, but it works. One can see that it really is short-circuiting: I don't know Haskell well enough to know why the `:: Int` on the end is needed, but I'm sure that that, too, can be worked around.