How can I have a function in haskell return either a boolean or a list of booleans? - haskell

I have function in haskell (lets call it 'dumb') which calls 3 different functions. These three different functions return different types, for example, a boolean or a list of booleans. How can I define function 'dumb' to either return a boolean or a list of booleans?
data Sumtype = givelist Integer | getprod Integer
prod :: Int -> Int
prod x = x*3
listnums :: Int -> [Int]
listnums x = [1...x]
dumb :: Sumtype -> (what comes here..?)
dumb (givelist x) -> listnums x
dum (getprod x) -> prod x

You make it return Either Boolean [Boolean]. But I'm suspicious about your motives. It sounds like an X/Y problem.

You're probably looking for the the Either type, although with it your function will return Either values. It's defined like this:
data Either a b = Left a | Right b
When you want to define a function that can return either a Bool or a list of Bools its type should look something like this:
dumb :: Either Bool [Bool]
In this case 'dumb' will be a function that doesn't take any arguments and return either a Bool or a list of Bools. In the function's body you can return a Bool like this:
Left bool
Or a list of bools like this:
Right [bool]
You can see a concrete example here: http://en.wikibooks.org/wiki/Haskell/More_on_datatypes#More_than_one_type_parameter
All that said though, the reason Sebastian asked you for more details is that Either is rarely used outside of error handling (AFAIK I know anyway). It's possible that in your case you don't really need it at all, but we can't be sure unless you tell us more about the other functions you use in 'dumb' and about your goals.

Unrelated Probems
It appears you are a beginner - welcome to Haskell! I strongly suggest you read and work through one of the many tutorials as that is more efficient and complete than asking individual questions.
Syntax
Let's start with correcting the syntax errors. Constructors, such as Givelist and Getprod must start with a capital letter. The function dumb was typo'ed once. Function definitions use = and not ->.
Types
Now we have type errors to address. The Sumtype uses Integer and you then switch to using Int. Lets just stick with Integer for simplicity.
With these fixes we get:
data Sumtype = Givelist Integer | Getprod Integer
prod :: Integer -> Integer
prod x = x*3
listnums :: Integer -> [Integer]
listnums x = [1...x]
dumb :: Sumtype -> (what comes here..?)
dumb (Givelist x) = listnums x
dumb (Getprod x) = prod x
The Question
You want to know "what comes here" where 'here' is the result type. As written, the function is actually invalid. One definition yields a list of integers, [Integer], while the other yields a single integer Integer. One solution is to use a sum type such as Either Integer [Integer] - this is very much like your pre-existing Sumtype:
dumb :: Sumtype -> Either Integer [Integer]
So now we need to return a constructor of Either in our function definitions. You can lookup the documentation or use :info Either in GHCi to learn the constructors if you don't have them memorized.
dumb (Givelist x) = Right (listnums x)
dumb (Getprod x) = Left (prod x)
Notice we had to use Left for the second case which returns an Integer, because the first type we wrote after Either (the left type) is Integer.

Related

Can't understand a simple Haskell function?

Can someone explain to me step by step what this function means?
select :: (a->a->Bool) -> a -> a -> a
As the comments pointed out, this is not a function definition, but just a type signature. It says, for any type a which you are free to choose, this function expects:
A function that takes two values of type a and gives a Bool
Two values of type a
and it returns another value of type a. So for example, we could call:
select (<) 1 2
where a is Int, since (<) is a function that takes two Ints and returns a Bool. We could not call:
select isPrefixOf 1 2
because isPrefixOf :: (Eq a) => [a] -> [a] -> Bool -- i.e. it takes two lists (provided that the element type supports Equality), but numbers are not lists.
Signatures can tell us quite a lot, however, due to parametericity (aka free theorems). The details are quite techincal, but we can intuit that select must return one of its two arguments, because it has no other way to construct values of type a about which it knows nothing (and this can be proven).
But beyond that we can't really tell. Often you can tell almost certainly what a function does by its signature. But as I explored this signature, I found that there were actually quite a few functions it could be, from the most obvious:
select f x y = if f x y then x else y
to some rather exotic
select f x y = if f x x && f y y then x else y
And the name select doesn't help much -- it seems to tell us that it will return one of the two arguments, but the signature already told us that.

First time using the Maybe type in Haskell, is my understanding wrong?

From my understanding, the Maybe type is something you can combine with another type. It lets you specify a condition for the inputs that you combined it with using the "Just... Nothing" format.
an example from my lecture slides is a function in Haskell that gives the square root of an input, but before doing so, checks to see if the input is positive.:
maybe_sqrt :: Maybe Float -> Maybe Float
maybe_sqrt maybe_x = case maybe_x of
Just x
| x >= 0 -> Just (sqrt x)
| otherwise -> Nothing
Nothing -> Nothing
However, I don't understand why this function uses both cases and guards. Why can't you just use guards, like this?:
maybe_sqrt :: Maybe Float -> Maybe Float
maybe_sqrt x
| x >= 0 = Just (sqrt x)
| otherwise = Nothing
the Maybe type is something you can combine with another type
Maybe is not a type†. It's a type constructor, i.e. you can use it to generate a type. For instance, Maybe Float is a type, but it's a different type from Float as such. A Maybe Float can not be used as a Float because, well, maybe it doesn't contain one!
But to calculate the square root, you need a Float. Well, no problem: in the Just case, you can just unwrap it by pattern matching! But pattern matching automatically prevents you from trying to unwrap a Float out of a Nothing value, which, well, doesn't contain a float which you could compare to anything.
Incidentally, this does not mean you to need trace every possible failure by pattern matching, all the way through your code. Luckily, Maybe is a monad. This means, if your function was a Kleisli arrow
maybe_sqrt :: Float -> Maybe Float
maybe_sqrt x
| x >= 0 = Just (sqrt x)
| otherwise = Nothing
(which is fine because it does accept a plain float) then you can still use this very easily with a Maybe Float as the argument:
GHCi> maybe_sqrt =<< Just 4
Just 2.0
GHCi> maybe_sqrt =<< Just (-1)
Nothing
GHCi> maybe_sqrt =<< Nothing
Nothing
†As discussed in the comments, there is some disagreement on whether we should nevertheless call Maybe type, or merely a type-level entity. As per research by Luis Casillas, it's actually rather Ok to call it a type. Anyway: my point was that Maybe Float is not “an OR-combination of the Maybe type (giving failure) and the Float type (giving values)”, but a completely new type with the structure of Maybe a and the optionally-contained elements of Float.
If your type were maybe_sqrt :: Float -> Maybe Float then that is how you would do it.
As it is, consider: what should your function do if your input is Nothing? Probably, you would want to return Nothing -- but why should your compiler know that?
The whole point of an "option" type like Maybe is that you can't ignore it -- you are required to handle all cases. If you want your Nothing cases to fall through to a Nothing output, Haskell provides a (somewhat) convenient facility for this:
maybe_sqrt x_in = do
x <- x_in
if x >= 0 then return sqrt x
else Nothing
This is the Maybe instance of Monad, and it does what you probably want. Any time you have a Maybe T expression, you can extract only the successful Just case with pattern <- expression. The only thing to remember is that non-Maybe bindings should use let pattern = expression instead.
This is more an extended comment than an answer. As leftaroundabout indicated, Maybe is an instance of Monad. It's also an instance of Alternative. You can use this fact to implement your function, if you like:
maybe_sqrt :: Maybe Float -> Maybe Float
maybe_sqrt maybe_x = do
x <- maybe_x
guard (x >= 0)
pure (sqrt x)
This is also more an extended comment (if this is your first time working with Maybe, you may not have encountered type classes yet; come back when you do). As others already said, x has type Maybe Float. But writing x >= 0 doesn't require x to be Float. What does it actually require? >= has type (Ord a) => a -> a -> Bool, which means it works for any types which are instances of Ord type class (and Maybe Float is one), and both arguments must have the same type. So 0 must be a Maybe Float as well! Haskell actually allows this, if Maybe Float belongs to the Num type class: which it doesn't in the standard library, but you could define an instance yourself:
instance Num a => Num (Maybe a) where
fromInteger x = Just (fromInteger x)
# this means 0 :: Maybe Float is Just 0.0
negate (Just x) = Just (negate x)
negate Nothing = Nothing
Just x + Just y = Just (x + y)
_ + _ = Nothing
# or simpler:
# negate = fmap negate
# (+) = liftA2 (+)
# similar for all remaining two argument functions
...
Now x >= 0 is meaningful. sqrt x is not; you'll need instances for Floating and Fractional as well. Of course, Just (sqrt x) will be Maybe (Maybe a), not Maybe a! But just sqrt x will do what you want.
The problem is that it works kind of by coincidence that Nothing >= 0 is False; if you checked x <= 0, Nothing would pass.
Also, it's generally a bad idea to define "orphan instances": i.e. the instance above should really only be defined in the module defining Maybe or in the module defining Num.

What is the Maybe type and how does it work?

I am just starting to program in Haskell, and I came across the following definition:
calculate :: Float -> Float -> Maybe Float
Maybe a is an ordinary data type defined as:
data Maybe a = Just a | Nothing
There are thus two possibilities: or you define a value of type a as Just a (like Just 3), or Nothing in case the query has no answer.
It is meant to be defined as a way to define output for non-total functions.
For instance: say you want to define sqrt. The square root is only defined for positive integers, you can thus define sqrt as:
sqrt x | x >= 0 = Just $ ...
| otherwise = Nothing
with ... a way to calculate the square root for x.
Some people compare Nothing with the "null pointer" you find in most programming languages. By default, you don't implement a null pointer for data types you define (and if you do, all these "nulls" look different), by adding Nothing you have a generic null pointer.
It can thus be useful to use Maybe to denote that it is possible no output can be calculated. You could of course also error on values less than 0:
sqrt x | x >= 0 = Just $ ...
| otherwise = error "The value must be larger or equal to 0"
But errors usually are not mentioned in the type signature, nor does a compiler have any problem if you don't take them into account. Haskell is also shifting to total functions: it's better to always try at least to return a value (e.g. Nothing) for all possible inputs.
If you later want to use the result of a Maybe a, you for instance need to write:
succMaybe :: Maybe Int -> Maybe Int
succMaybe (Just x) = Just (x+1)
succMaybe _ = Nothing
But by writing Just for the first case, you somehow warn yourself that it is possible that Nothing can occur. You can also get rid of the Maybe by introducing a "default" value:
justOrDefault :: a -> Maybe a -> a
justOrDefault _ (Just x) = x
justOrDefault d _ = d
The builtin maybe function (note the lowercase), combines the two previous functions:
maybe :: b -> (a -> b) -> Maybe a -> b
maybe _ f (Just x) = f x
maybe z _ Nothing = z
So you specify a b (default value) together with a function (a -> b). In case Maybe a is Just x, the function is applied to it and returned, in case the input value is Nothing, the default value will be used.
Working with Maybe a's can be hard, because you always need to take the Nothing case into account, to simplify this you can use the Maybe monad.
Tom Schrijvers also shows that Maybe is the successor function in type algebra: you add one extra value to your type (Either is addition and (,) is the type-algebraic equivalent of multiplication).

Why am I receiving this syntax error - possibly due to bad layout?

I've just started trying to learn haskell and functional programming. I'm trying to write this function that will convert a binary string into its decimal equivalent. Please could someone point out why I am constantly getting the error:
"BinToDecimal.hs":19 - Syntax error in expression (unexpected `}', possibly due to bad layout)
module BinToDecimal where
total :: [Integer]
total = []
binToDecimal :: String -> Integer
binToDecimal a = if (null a) then (sum total)
else if (head a == "0") then binToDecimal (tail a)
else if (head a == "1") then total ++ (2^((length a)-1))
binToDecimal (tail a)
So, total may not be doing what you think it is. total isn't a mutable variable that you're changing, it will always be the empty list []. I think your function should include another parameter for the list you're building up. I would implement this by having binToDecimal call a helper function with the starting case of an empty list, like so:
binToDecimal :: String -> Integer
binToDecimal s = binToDecimal' s []
binToDecimal' :: String -> [Integer] -> Integer
-- implement binToDecimal' here
In addition to what #Sibi has said, I would highly recommend using pattern matching rather than nested if-else. For example, I'd implement the base case of binToDecimal' like so:
binToDecimal' :: String -> [Integer] -> Integer
binToDecimal' "" total = sum total -- when the first argument is the empty string, just sum total. Equivalent to `if (null a) then (sum total)`
-- Include other pattern matching statements here to handle your other if/else cases
If you think it'd be helpful, I can provide the full implementation of this function instead of giving tips.
Ok, let me give you hints to get you started:
You cannot do head a == "0" because "0" is String. Since the type of a is [Char], the type of head a is Char and you have to compare it with an Char. You can solve it using head a == '0'. Note that "0" and '0' are different.
Similarly, rectify your type error in head a == "1"
This won't typecheck: total ++ (2^((length a)-1)) because the type of total is [Integer] and the type of (2^((length a)-1)) is Integer. For the function ++ to typecheck both arguments passed to it should be list of the same type.
You are possible missing an else block at last. (before the code binToDecimal (tail a))
That being said, instead of using nested if else expression, try to use guards as they will increase the readability greatly.
There are many things we can improve here (but no worries, this is perfectly normal in the beginning, there is so much to learn when we start Haskell!!!).
First of all, a string is definitely not an appropriate way to represent a binary, because nothing prevents us to write "éaldkgjasdg" in place of a proper binary. So, the first thing is to define our binary type:
data Binary = Zero | One deriving (Show)
We just say that it can be Zero or One. The deriving (Show) will allow us to have the result displayed when run in GHCI.
In Haskell to solve problem we tend to start with a more general case to dive then in our particular case. The thing we need here is a function with an additional argument which holds the total. Note the use of pattern matching instead of ifs which makes the function easier to read.
binToDecimalAcc :: [Binary] -> Integer -> Integer
binToDecimalAcc [] acc = acc
binToDecimalAcc (Zero:xs) acc = binToDecimalAcc xs acc
binToDecimalAcc (One:xs) acc = binToDecimalAcc xs $ acc + 2^(length xs)
Finally, since we want only to have to pass a single parameter we define or specific function where the acc value is 0:
binToDecimal :: [Binary] -> Integer
binToDecimal binaries = binToDecimalAcc binaries 0
We can run a test in GHCI:
test1 = binToDecimal [One, Zero, One, Zero, One, Zero]
> 42
OK, all fine, but what if you really need to convert a string to a decimal? Then, we need a function able to convert this string to a binary. The problem as seen above is that not all strings are proper binaries. To handle this, we will need to report some sort of error. The solution I will use here is very common in Haskell: it is to use "Maybe". If the string is correct, it will return "Just result" else it will return "Nothing". Let's see that in practice!
The first function we will write is to convert a char to a binary. As discussed above, Nothing represents an error.
charToBinary :: Char -> Maybe Binary
charToBinary '0' = Just Zero
charToBinary '1' = Just One
charToBinary _ = Nothing
Then, we can write a function for a whole string (which is a list of Char). So [Char] is equivalent to String. I used it here to make clearer that we are dealing with a list.
stringToBinary :: [Char] -> Maybe [Binary]
stringToBinary [] = Just []
stringToBinary chars = mapM charToBinary chars
The function mapM is a kind of variation of map which acts on monads (Maybe is actually a monad). To learn about monads I recommend reading Learn You a Haskell for Great Good!
http://learnyouahaskell.com/a-fistful-of-monads
We can notice once more that if there are any errors, Nothing will be returned.
A dedicated function to convert strings holding binaries can now be written.
binStringToDecimal :: [Char] -> Maybe Integer
binStringToDecimal = fmap binToDecimal . stringToBinary
The use of the "." function allow us to define this function as an equality with another function, so we do not need to mention the parameter (point free notation).
The fmap function allow us to run binToDecimal (which expect a [Binary] as argument) on the return of stringToBinary (which is of type "Maybe [Binary]"). Once again, Learn you a Haskell... is a very good reference to learn more about fmap:
http://learnyouahaskell.com/functors-applicative-functors-and-monoids
Now, we can run a second test:
test2 = binStringToDecimal "101010"
> Just 42
And finally, we can test our error handling system with a mistake in the string:
test3 = binStringToDecimal "102010"
> Nothing

Haskell Boolean Function implementation

I am trying to solve following problem -- given all selectors(e^i_n) and some boolean functions({f_1, f_2, f_n}) enumerate all functions of n arguments in closure(in [f_1,f_2,..f_n]).
So, I implement BooleanFunctionClass and existencial BooleanFunction type.
Are they aganist spirit of Haskell?
class BooleanFunctionClass a where
arity :: a -> Int
instance BooleanFunctionClass Bool where
arity _ = 0
instance BooleanFunctionClass a => BooleanFunctionClass (Bool -> a) where
arity f = arity (f True) + 1
data BooleanFunction = forall a. (BooleanFunctionClass a) => BooleanFunction a String
instance Show BooleanFunction where
show (BooleanFunction _ str) = show str
But I have no idea how implement selector(function of n arguments, that returns k-th).
I want selector :: Int -> Int -> BooleanFunction. Any suggestions?
PS. Sorry. I do not know, how insert TeX in Markdown.
I'm not sure exactly what you're trying to achieve, but if you want the arity to be checked at compile time, lists probably aren't going to do the job (as you suggested in the comments).
You'll need tuples, or something like it. The nicest way to deal with variable sized tuples is Template Haskell. Also TupleTH has already done a lot of the work for you regarding processing tuples in a type safe way.

Resources