Is it possible to overload logical operators (&& eg.) In Haskell?

I am working with multi-valued logic and am trying to overload basic boolean functions.

I have no problem overloading Num

and operators Eq

, but I don't know how to overload &&, ||

and not

.

Is it possible? Thanks for answers!

+3


source to share


5 answers


Haskell doesn't actually overload (= ad-hoc polymorphism) at all. +

, *

etc. - these are not functions, but methods of a class: their "overloading" is more like defining concrete descendants of an OO interface / purely abstract class than function overloading, for example, in C ++.

OTOH logical operators are just regular functions that are defined once and for all in the prelude.

However, in Haskell, infix operators are mostly treated as a special type of function name, they are not part of the actual syntax definition. Nothing prevents you from defining new, different operators with the same purpose, for example.



class Booly b where
  true :: b
  false :: b
  (&&?) :: b -> b -> b
  (||?) :: b -> b -> b
infixr 3 &&?
infixr 2 ||?

instance Booly Bool where
  true = True
  false = False
  (&&?) = (&&)
  (||?) = (||)

instance Booly MVBool where
  true = ...

      

In fact, it is sufficient if the new names are eliminated using the module classifiers:

import Prelude hiding ((&&), (||))
import qualified Prelude

class Booly b where
  true :: b
  false :: b
  (&&) :: b -> b -> b
  (||) :: b -> b -> b
infixr 3 &&
infixr 2 ||

instance Booly Bool where
  true = True
  false = False
  (&&) = (Prelude.&&)
  (||) = (Prelude.||)

      

+10


source


There is no such thing as monkey-like overriding in Haskell.

It is also impossible to connect an extension to something that was not created for the extension.

You can just shade the definition for example. &&

, but this 1) will not affect semantics &&

in other modules and 2) will be confusing.



So, I would use something simple:

-- laws should be defined for the class and instances QuickChecked/proved against these laws
class Logic a where
  (&.&) :: a -> a -> a
  (|.|) :: a -> a -> a
  ...

instance Logic Bool where
  (&.&) = (&&)
  (|.|) = (||)

data MultiBool = False' | True' | Perhaps | CouldBe | Possibly | Unlikely

instance Logic MultiBool where
  ...

      

+2


source


No, It is Immpossible. The type &&

is Bool -> Bool -> Bool

, and Haskell does not allow ad-hoc overloading. You can shadow the declaration, but then you cannot use the operator for both boolean and your mvl values ​​in the same unskilled module.

I recommend you define similar operators such as &&?

for your mvls.

+1


source


You cannot override them, but you can define your own.

infixr 3 <&&> <||>

<&&> :: ??? -> ??? -> ???
<&&> ...

      

+1


source


(&&)

defined as

(&&) :: Bool -> Bool -> Bool

      

Therefore, if you do not download Prelude

or load it, you cannot overload this operator.

However, there is a class that does more or less than what you are looking for: Data.Bits

with signatures like:

(.&.) :: Bits a => a -> a -> a
(.|.) :: Bits a => a -> a -> a
complement :: Bits a => a -> a

      

Data.Bits

commonly used to represent bitwise operations. You can choose to ignore the rest of the operators (return the default) or assign a useful property to it.

Otherwise, you can define similar operators. In this case, one betters first defines the class:

class Logic a where
    land :: a -> a -> a
    lor :: a -> a -> a
    lnot :: a -> a
    lnand :: a -> a -> a
    lnand x = lnot . land x
    lnor :: a -> a -> a
    lnor x = lnot . lor x

      

+1


source







All Articles