Where is Haskell's if' function? - haskell

If you use pointfree on the code \b t f -> if b then t else f, the answer you get is if'.
Where is if' defined?

It's worth mentioning that the if' function exists in base since version 4.7, but it's called bool (in style with either and maybe).
bool :: a -> a -> Bool -> a
bool f _ False = f
bool _ t True = t
is defined in Data.Bool.

According to Hayoo, it is defined in the following three packages:
if' :: Bool -> a -> a -> a
utility-ht - Data.Bool.HT
if-then-else as function.
Example:
if' (even n) "even" $
if' (isPrime n) "prime" $
"boring"
plailude - Plailude
If True then the first value, else the second.
CLASE - Data.Cursor.CLASE.Util
The two main search engines for Haskell that I know of are Hoogle and Hayoo.

Related

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.)

Monadic if else

I am new to Haskell and want to generate an Arbitrary tree.
So my first idea is to create an arbitary bool, if it is true then return an empty tree and else create a non-empty one:
instance (Arbitrary a) => Arbitrary (BinaryTree a)
arbitrary = do
createNonEmpty <- arbitrary
if createNonEmpty
then return Nil
else generateNonEmptyTree
But this pattern of creating the bool and use it just for that if seems a bit odd and it feels like there should be a more idiomatic way.
Is there already some kind of "monadic if" in the standard library that I could use like
arbitrary = ifM arbitrary (return Nil) (generateNonEmptyTree)
Or what else is the most idiomatic way to solve this?
For QuickCheck in particular, I'd use oneof:
arbitrary = oneof [return Nil, generateNonEmptyTree]
It does essentially what you propose in your question (generate a one-off value, then use it immediately):
oneof :: [Gen a] -> Gen a
oneof [] = error "QuickCheck.oneof used with empty list"
oneof gs = choose (0,length gs - 1) >>= (gs !!)
But since it's a library function, this means you don't have to see the one-off values in your own code.
My general solution to the "use once binding" is -XLambdaCase:
instance (Arbitrary a) => Arbitrary (BinaryTree a)
arbitrary = arbitrary >>= \case
True -> return Nil
False -> generateNonEmptyTree
Alternately, you could use something like
bool :: a -> a -> Bool -> a
bool f _ False = f
bool _ t True = t
(Bool's equivalent to either or foldr)
instance (Arbitrary a) => Arbitrary (BinaryTree a)
arbitrary = bool generateNonEmptyTree (return Nil) =<< arbitrary

Function composition in boolean operators

I don't have much FP experience and I think I'm just missing a key insight from someone more versed. I'm writing a small, embedded, functional, strictly- and invariantly-typed language.
I'll be using Haskell-like syntax in this question.
The following signatures are for predefined functions with types that are what you'd expect:
and :: bool -> bool -> bool -- boolean and
lt :: int -> int -> bool -- less than
gt :: int -> int -> bool -- greater than
len :: list -> int -- list length
My job is to compose these functions (and constants) to form an expression which has the following signature:
λ :: list -> bool
The result of which is whether a list has a length between 1 and 99.
Constraints: This language (currently) only supports function application and function composition. No lambda expressions, no higher-order functions.
This is how far I've gotten:
and . ((gt 0) . len) :: list -> bool -> bool
This takes a list, checks if it's length is greater than 0, then a boolean and returns the "and" of both arguments.
But now I'm stuck. How would you continue from here in traditional functional languages? Is there a way to express a solution without lambdas/closures?
I'm open to add new features to the language, as long as it remains underpowered and simple.
This is called pointfree style and there is a nice tool on the web for transforming Haskell code to it. Converting f xs = (length xs > 0) && (length xs < 100) gives f = ap ((&&) . (> 0) . length) ((< 100) . length). So you are just missing the ap function (see also Understanding `ap` in a point-free function in Haskell). For your application it should have type (a -> b -> c) -> (a -> b) -> (a -> c) and be built-in along with ..

Is it possible to overload logical operators (&& e.g.) in 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

"maybe"-like function for Bool and List?

Sometimes i find myself progamming the pattern "if the Bool is not false" or "if the list is not empty use it, otherwise use something else".
I am looking for functions for Bool and List that are what the "maybe" function is to Maybe. Are there any?
Update: I meant to use the Bool-case as a generalization of the List-case. For example when working with Data.Text as T:
if T.null x then x else foo x
I am looking to reduce such boiler plate code.
maybe is the catamorphism of the Maybe type.
foldr is the catamorphism of the list type.
Data.Bool.bool is the catamorphism of the Bool type.
If you had used maybe like: maybe x (const y)
You could use: foldr (const (const y)) x
Your example if T.null x then x else foo x could be written with bool as
bool foo id (T.null x) x
(it takes the False case first, the opposite of if)
I think the answer is probably that there isn't such a generic function. As djv says, you can perhaps build on Data.Monoid to write one, something like:
maybe' :: (Eq a, Monoid a) => b -> (a -> b) -> a -> b
maybe' repl f x = if x == mempty then repl else f x
But I don't know of any functions in the standard library like that (or any that could easily be composed together to do so).
Check Data.Monoid, it's a typeclass describing data types which have a designated empty value and you can pattern-match on it to write your generic function. There are instances for Bool with empty value False and for List with empty value [].

Resources