Is it possible to overload logical operators (&& e.g.) in Haskell? - haskell

I'm working with many-valued logic and trying to overload basic logic functions.
I haven't problem with overloading Num and Eq operators, but I don't know how to overload &&, || and not.
Is it possible? Thanks for answers!

Haskell doesn't really have overloading (=ad-hoc-polymorphism) at all. +, * etc. are not functions but class methods: “overloading” them is more like defining concrete descendants of an OO interface / purely-abstract class than overloading functions in, say, C++.
The logical operators OTOH are just ordinary functions, which are defined in the Prelude once and for all.
However, in Haskell, infix operators are mostly treated just as a special kind of function name, they're not part of the actual syntax definition. Nothing prevents you from defining new, different operators with the same purpose, e.g.
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's enough if the new names are disambiguated by module qualifiers:
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.||)

There is no such thing as overriding in Haskell in the monkeypatching sense.
There's also no way to hook an extension into something that wasn't built to be extended.
You can simply shadow the definition of e.g. && but this would 1) not affect the semantics of && in other modules and 2) would be confusing.
So I would use something as simple as:
-- 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
...

No, it's not possible. The type of && is Bool -> Bool -> Bool, and Haskell doesn't allow ad-hoc overloading. You can shadow the declaration, but then you can't use the operator for both booleans and your mvl values in the same module without qualification.
I recommend you define similar-looking operators such as &&? for your mvls.

You can't override them, but you can define your own.
infixr 3 <&&> <||>
<&&> :: ??? -> ??? -> ???
<&&> ...

(&&) is defined as
(&&) :: Bool -> Bool -> Bool
So unless you don't load the Prelude, or load it qualified, you cannot overload that operator.
There is however a typeclass that does more or less 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 is normally used to represent bitwise operations. You could decide to ignore the remaining operators (return some default value) or assign a useful property to it.
Otherwise you can define similar operators. In that case one betters defines a typeclass first:
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

Related

Pattern matching with Alternative empty or Applicative pure

I know it is possible, to pattern match against (named) constructors like so:
f1 :: Maybe a -> Bool
f1 Nothing = False
f1 (Just x) = True -- in reality have something that uses x here
f2 :: [a] -> Int
f2 [] = False
f2 x = True
How can I write such a function for general Alternatives similar to
f :: (Alternative m) => m a -> Bool
f empty = False
f x = True
If I try this, I get the error Parse error in pattern: empty. Which makes sense, I guess, as empty as a function here and not a constructor. But how can I accomplish this for general Alternatives idiomatically?
Edit 1:
My actual goal is to define a Monad instance (and probably also a MonadPlus instance) for a custom result type. Instead of the basic Either Error Result type, it should support a Maybe Error (and if possible also other Alternatives like [Error]) as error type and also some Applicative as result type in order to support lazy evaluation, for example with the result type (Maybe Error, [Tokens]) of a tokenizer.
I'd like something similar to
instance (Alterantive mErr, Applicative mRes) => Monad (mErr e, mRes a) where
return x = (empty, pure x)
(empty, pure x) >>= f = f x
(err, x) >>= f = (err, x)
The best you can do is:
f :: (Eq (m a), Alternative m) => m a -> Bool
f x | x == empty = False
| otherwise = True
It is in fact possible using -XPatternSynonyms and -XViewPatterns:
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ViewPatterns #-}
import Control.Applicative (empty)
pattern Empty :: (Eq (m a), Alternative m) => m a
pattern Empty <- ((==) empty -> True)
f :: (Eq (m a), Alternative m) => m a -> Bool
f Empty = False
f _ = True
Slipping in an Eq constraint, as in mithrandi's answer, is indeed the best that can be done. In any case, it is worth emphasising that it comes at a cost: we are now stuck with an Eq constant that would be unnecessary were we merely pattern match against, say, [] or Nothing. A common way to avoid this problem is using null :: Foldable t => t a -> Bool. Here, however, that option is not great either, as Foldable is largely unrelated to Alternative and rather alien to your use case. In particular, there is no guarantee that, in the general case, there will be just one value for which null holds, which means it might conceivably hold for values that aren't the empty of the relevant Alternative instance.
Ultimately, then, the only tool that would fully fit the requirements might well be some Alternative subclass with an isEmpty method. I don't think that exists anywhere, and the power-to-weight ratio doesn't seem encouraging when it comes to conjuring such a thing.

Pattern Matching for a new data

I created a new type with some functions
data Gate = MakeGate (Bool -> Bool -> Bool)
andGate = MakeGate (&&)
orGate = MakeGate (||)
Now I want to add this type to a new instance of Eq with pattern matching, but I actually get alot of error messages. What I tried so far is
instace Eq Gate where
MakeGate True == MakeGate True = True
The Error Message is: "Couldn't match expected type 'Bool -> Bool -> Bool' with actual type 'Bool'"
I was thinking that Bool -> Bool -> Bool means something similar to the (&&) or (||) functions. But it doesn't work that way.
What am I missing?
You probably want to find out if the two functions that the MakeGate data constructors wrap always produce the same result of the same input.
We can only find this out by performing an exhaustive search: for both functions calculate the result for all possible inputs, and each time comparing the output. We thus could write it like:
type GateFunc = Bool -> Bool -> Bool
eqGate :: GateFunc -> GateFunc -> Bool
eqGate f g = f False False == g False False
&& f False True == g False True
&& f True False == g True False
&& f True True == g True True
and then write it as:
instance Eq Gate where
MakeGate f == MakeGate g = eqGate f g
The above is however not very elegant: we can do better by generating lists:
eqGate :: GateFunc -> GateFunc -> Bool
eqGate f g = (f <$> ft <*> ft) == (g <$> ft <*> ft)
where ft = [False, True]
Or even less code:
import Data.Function(on)
eqGate = on (==) ((<*> ft) . (<$> ft))
where ft = [False, True]
Note that for functions with a small (at least finite!) input space, and an output type that is an instance of Eq, this can be done, but in general one can not compare two functions. Furthermore even if the two functions have a finite input space, it can go wrong (since the functions could get stuck into an infinite loop). Determining whether two functions are equal is an undecidable problem.
You can't really pattern match functions in Haskell.
MakeGate is a constructor that has the type: (Bool -> Bool -> Bool) -> Gate
But you're giving it a Bool (True). MakeGate True doesn't typecheck.
Maybe you meant MakeGate f == MakeGate g = f == g or something like that?
I'm not sure what you're trying to do, but function equivalence isn't trivial and pattern matching is for constructors, not functions.
I think what you really want is
data Gate = AndGate | OrGate | ...
MakeGate does not wrap a Boolean value; it wraps a function. I'm not sure how you would define an Eq instance for Gate, because you can't compare functions for equality. The syntax, though, would be
instance Eq Gate where
(MakeGate f) == (MakeGate g) = ???
The ??? would be the actual equality test, but like I said, it's not clear what you would put here, because you can't use, for instance, f == g.
You cannot define a meaningful Eq instance on your Gate type, since it contains a function, and functions cannot be compared for equality.
More to the point, though, your question seems confused about a variety of different things about Haskell specifically and higher-order functional programming in general. Consider finding a course, book, or other resource to help you learn in a structured, principled way. (Asking for such resources is off-topic on Stack Overflow, so I will refrain from making specific suggestions here.)

Getting all function arguments in haskel as list

Is there a way in haskell to get all function arguments as a list.
Let's supose we have the following program, where we want to add the two smaller numbers and then subtract the largest. Suppose, we can't change the function definition of foo :: Int -> Int -> Int -> Int. Is there a way to get all function arguments as a list, other than constructing a new list and add all arguments as an element of said list? More importantly, is there a general way of doing this independent of the number of arguments?
Example:
module Foo where
import Data.List
foo :: Int -> Int -> Int -> Int
foo a b c = result!!0 + result!!1 - result!!2 where result = sort ([a, b, c])
is there a general way of doing this independent of the number of arguments?
Not really; at least it's not worth it. First off, this entire idea isn't very useful because lists are homogeneous: all elements must have the same type, so it only works for the rather unusual special case of functions which only take arguments of a single type.
Even then, the problem is that “number of arguments” isn't really a sensible concept in Haskell, because as Willem Van Onsem commented, all functions really only have one argument (further arguments are actually only given to the result of the first application, which has again function type).
That said, at least for a single argument- and final-result type, it is quite easy to pack any number of arguments into a list:
{-# LANGUAGE FlexibleInstances #-}
class UsingList f where
usingList :: ([Int] -> Int) -> f
instance UsingList Int where
usingList f = f []
instance UsingList r => UsingList (Int -> r) where
usingList f a = usingList (f . (a:))
foo :: Int -> Int -> Int -> Int
foo = usingList $ (\[α,β,γ] -> α + β - γ) . sort
It's also possible to make this work for any type of the arguments, using type families or a multi-param type class. What's not so simple though is to write it once and for all with variable type of the final result. The reason being, that would also have to handle a function as the type of final result. But then, that could also be intepreted as “we still need to add one more argument to the list”!
With all respect, I would disagree with #leftaroundabout's answer above. Something being
unusual is not a reason to shun it as unworthy.
It is correct that you would not be able to define a polymorphic variadic list constructor
without type annotations. However, we're not usually dealing with Haskell 98, where type
annotations were never required. With Dependent Haskell just around the corner, some
familiarity with non-trivial type annotations is becoming vital.
So, let's take a shot at this, disregarding worthiness considerations.
One way to define a function that does not seem to admit a single type is to make it a method of a
suitably constructed class. Many a trick involving type classes were devised by cunning
Haskellers, starting at least as early as 15 years ago. Even if we don't understand their
type wizardry in all its depth, we may still try our hand with a similar approach.
Let us first try to obtain a method for summing any number of Integers. That means repeatedly
applying a function like (+), with a uniform type such as a -> a -> a. Here's one way to do
it:
class Eval a where
eval :: Integer -> a
instance (Eval a) => Eval (Integer -> a) where
eval i = \y -> eval (i + y)
instance Eval Integer where
eval i = i
And this is the extract from repl:
λ eval 1 2 3 :: Integer
6
Notice that we can't do without explicit type annotation, because the very idea of our approach is
that an expression eval x1 ... xn may either be a function that waits for yet another argument,
or a final value.
One generalization now is to actually make a list of values. The science tells us that
we may derive any monoid from a list. Indeed, insofar as sum is a monoid, we may turn arguments to
a list, then sum it and obtain the same result as above.
Here's how we can go about turning arguments of our method to a list:
class Eval a where
eval2 :: [Integer] -> Integer -> a
instance (Eval a) => Eval (Integer -> a) where
eval2 is i = \j -> eval2 (i:is) j
instance Eval [Integer] where
eval2 is i = i:is
This is how it would work:
λ eval2 [] 1 2 3 4 5 :: [Integer]
[5,4,3,2,1]
Unfortunately, we have to make eval binary, rather than unary, because it now has to compose two
different things: a (possibly empty) list of values and the next value to put in. Notice how it's
similar to the usual foldr:
λ foldr (:) [] [1,2,3,4,5]
[1,2,3,4,5]
The next generalization we'd like to have is allowing arbitrary types inside the list. It's a bit
tricky, as we have to make Eval a 2-parameter type class:
class Eval a i where
eval2 :: [i] -> i -> a
instance (Eval a i) => Eval (i -> a) i where
eval2 is i = \j -> eval2 (i:is) j
instance Eval [i] i where
eval2 is i = i:is
It works as the previous with Integers, but it can also carry any other type, even a function:
(I'm sorry for the messy example. I had to show a function somehow.)
λ ($ 10) <$> (eval2 [] (+1) (subtract 2) (*3) (^4) :: [Integer -> Integer])
[10000,30,8,11]
So far so good: we can convert any number of arguments into a list. However, it will be hard to
compose this function with the one that would do useful work with the resulting list, because
composition only admits unary functions − with some trickery, binary ones, but in no way the
variadic. Seems like we'll have to define our own way to compose functions. That's how I see it:
class Ap a i r where
apply :: ([i] -> r) -> [i] -> i -> a
apply', ($...) :: ([i] -> r) -> i -> a
($...) = apply'
instance Ap a i r => Ap (i -> a) i r where
apply f xs x = \y -> apply f (x:xs) y
apply' f x = \y -> apply f [x] y
instance Ap r i r where
apply f xs x = f $ x:xs
apply' f x = f [x]
Now we can write our desired function as an application of a list-admitting function to any number
of arguments:
foo' :: (Num r, Ord r, Ap a r r) => r -> a
foo' = (g $...)
where f = (\result -> (result !! 0) + (result !! 1) - (result !! 2))
g = f . sort
You'll still have to type annotate it at every call site, like this:
λ foo' 4 5 10 :: Integer
-1
− But so far, that's the best I can do.
The more I study Haskell, the more I am certain that nothing is impossible.

Haskell, Instance, Type Constraints

I created in Haskell a new class Eqa
class Eqa a where
(=~) :: a -> a -> Bool
(/~) :: a -> a -> Bool
and want to define (=~) same as (==) from the Prelude. So I tried
instance Eqa Int where
x=~y = x==y
x/~y = x/=y
but this only works for Int (of course).
How do I have to change my code that this works with all numerical types?
Why not just write
(=~) :: Num a => a -> a -> Bool
x=~y = x==y
If you don't actually need the code to be different for different types, why do you need a class at all?
All you have to do is to bind a to Num a or
instance Num a => Eqa a where
x=~y = x==y
x/~y = x/=y
For more information, take a look at Numeric Types subsection of Real World Haskell to understand which class is related to each numerical types.

Get a list of the instances in a type class in Haskell

Is there a way to programmatically get a list of instances of a type class?
It strikes me that the compiler must know this information in order to type check and compile the code, so is there some way to tell the compiler: hey, you know those instances of that class, please put a list of them right here (as strings or whatever some representation of them).
You can generate the instances in scope for a given type class using Template Haskell.
import Language.Haskell.TH
-- get a list of instances
getInstances :: Name -> Q [ClassInstance]
getInstances typ = do
ClassI _ instances <- reify typ
return instances
-- convert the list of instances into an Exp so they can be displayed in GHCi
showInstances :: Name -> Q Exp
showInstances typ = do
ins <- getInstances typ
return . LitE . stringL $ show ins
Running this in GHCi:
*Main> $(showInstances ''Num)
"[ClassInstance {ci_dfun = GHC.Num.$fNumInteger, ci_tvs = [], ci_cxt = [], ci_cls = GHC.Num.Num, ci_tys = [ConT GHC.Integer.Type.Integer]},ClassInstance {ci_dfun = GHC.Num.$fNumInt, ci_tvs = [], ci_cxt = [], ci_cls = GHC.Num.Num, ci_tys = [ConT GHC.Types.Int]},ClassInstance {ci_dfun = GHC.Float.$fNumFloat, ci_tvs = [], ci_cxt = [], ci_cls = GHC.Num.Num, ci_tys = [ConT GHC.Types.Float]},ClassInstance {ci_dfun = GHC.Float.$fNumDouble, ci_tvs = [], ci_cxt = [], ci_cls = GHC.Num.Num, ci_tys = [ConT GHC.Types.Double]}]"
Another useful technique is showing all instances in scope for a given type class using GHCi.
Prelude> :info Num
class (Eq a, Show a) => Num a where
(+) :: a -> a -> a
(*) :: a -> a -> a
(-) :: a -> a -> a
negate :: a -> a
abs :: a -> a
signum :: a -> a
fromInteger :: Integer -> a
-- Defined in GHC.Num
instance Num Integer -- Defined in GHC.Num
instance Num Int -- Defined in GHC.Num
instance Num Float -- Defined in GHC.Float
instance Num Double -- Defined in GHC.Float
Edit: The important thing to know is that the compiler is only aware of type classes in scope in any given module (or at the ghci prompt, etc.). So if you call the showInstances TH function with no imports, you'll only get instances from the Prelude. If you have other modules in scope, e.g. Data.Word, then you'll see all those instances too.
See the template haskell documentation: http://hackage.haskell.org/packages/archive/template-haskell/2.5.0.0/doc/html/Language-Haskell-TH.html
Using reify, you can get an Info record, which for a class includes its list of instances. You can also use isClassInstance and classInstances directly.
This is going to run into a lot of problems as soon as you get instance declarations like
instance Eq a => Eq [a] where
[] == [] = True
(x:xs) == (y:ys) = x == y && xs == ys
_ == _ = False
and
instance (Eq a,Eq b) => Eq (a,b) where
(a1,b1) == (a2,b2) = a1 == a2 && b1 == b2
along with a single concrete instance (e.g. instance Eq Bool).
You'll get an infinite list of instances for Eq - Bool,[Bool],[[Bool]],[[[Bool]]] and so on, (Bool,Bool), ((Bool,Bool),Bool), (((Bool,Bool),Bool),Bool) etcetera, along with various combinations of these such as ([((Bool,[Bool]),Bool)],Bool) and so forth. It's not clear how to represent these in a String; even a list of TypeRep would require some pretty smart enumeration.
The compiler can (try to) deduce whether a type is an instance of Eq for any given type, but it doesn't read in all the instance declarations in scope and then just starts deducing all possible instances, since that will never finish!
The important question is of course, what do you need this for?
I guess, it's not possible. I explain you the implementation of typeclasses (for GHC), from it, you can see, that the compiler has no need to know which types are instance of a typeclass. It only has to know, whether a specific type is instance or not.
A typeclass will be translated into a datatype. As an example, let's take Eq:
class Eq a where
(==),(/=) :: a -> a -> Bool
The typeclass will be translated into a kind of dictionary, containing all its functions:
data Eq a = Eq {
(==) :: a -> a -> Bool,
(/=) :: a -> a -> Bool
}
Each typeclass constraint is then translated into an extra argument containing the dictionary:
elem :: Eq a => a -> [a] -> Bool
elem _ [] = False
elem a (x:xs) | x == a = True
| otherwise = elem a xs
becomes:
elem :: Eq a -> a -> [a] -> Bool
elem _ _ [] = False
elem eq a (x:xs) | (==) eq x a = True
| otherwise = elem eq a xs
The important thing is, that the dictionary will be passed at runtime. Imagine, your project contains many modules. GHC doesn't have to check all the modules for instances, it just has to look up, whether an instance is defined anywhere.
But if you have the source available, I guess an old-style grep for the instances would be sufficient.
It is not possible to automatically do this for existing classes. For your own class and instances thereof you could do it. You would need to declare everything via Template Haskell (or perhaps the quasi-quoting) and it would automatically generate some strange data structure that encodes the declared instances. Defining the strange data structure and making Template Haskell do this are details left to whomever has a use case for them.
Perhaps you could add some Template Haskell or other magic to your build to include all the source files as text available at run-time (c.f. program quine). Then your program would 'grep itself'...

Resources