Haskell getting to the tuple - haskell

I have a function in Haskell defined as (Error is a data type)
data Error a = Woops | Nice a deriving (Eq, Ord, Show)
mixIt :: Int -> Int -> (Error (Int, Int))
How can I get to the return tuple, I have tried;
fst (mixIt 2 2)
But it gives an error?

fst is a function with the type (a, b) -> a (well, we're using it in a more specific way, as (Int, Int) -> Int) but we're applying it to mixIt 2 2 which has the type Error (Int, Int). This is the source of our error.
In order to fix it we need to inspect the Error value we get back from mixIt by pattern matching on it
case mixIt 2 2 of
Nice tuple -> fst tuple
We can explicitly pattern match on the case where we have a Nice constructor which has the tuple we want as an argument. However there's a problem because mixIt might also return Woops, the other constructor of Error. We need to handle that case separately otherwise our program will fail at runtime (a very bad thing)
case mixIt 2 2 of
Nice tuple -> fst tuple
Whoops -> ... some Haskell code to produce another tuple ...
once you fill in that last branch of the case expression you're set to go.

Related

(Haskell) Can't understand error : No instance for (Ord a) arising from a use of ‘’

I'm trying to code a function that takes a list of string (containing actions to do on the lists inside the tuple) and a tuple of 2 lists of Int as parameters (testReturn).
The function is supposed to execute an action on the Int lists, checks if the first list in the tuple is in ascending order, and then returns a boolean depending on the result.
This code doesn't compile, and I'm not sure about a few things.
My code :
testReturn :: [[Char]] -> ([a], [b]) -> Bool
testReturn [] b = orderedCheck $ fst b
testReturn (a:as) b
| a == "sa" = testReturn as (saFunc $ fst b, snd b)
orderedCheck :: (Ord a) => [a] -> Bool
orderedCheck [] = True
orderedCheck [x] = True
orderedCheck (x:y:xs) = x <= y && orderedCheck (y:xs)
saFunc :: [a] -> [a]
saFunc x
| length x <= 1 = x
saFunc (x:y:xs) = (y:x:xs)
I know that the orderedCheck and saFunc functions work
I'm concerned about :
[[Char]] : Not sure if writing this is right or not, and not sure if it really means a list of strings.
orderedCheck $ fst b : this is the part where I have a GHC error : "No instance for (Ord a) arising from a use of ‘orderedCheck’ ",I looked around and I can't understand what does it mean.
I heard somewhere else that the use of fst and snd may be a bit edgy (is it?), but I don't know how to do without it.
Could you guys please help me understand my errors in order to fix my code?
Thanks!
[[Char]] : Not sure if writing this is right or not, and not sure if it really means a list of strings.
Yes, it does mean a list of strings - that is, the type [String]. This is the same as [[Char]] because in Haskell String and [Char] are type synonyms, literally different ways of referring to the exact same thing. So putting a pair of square brackets round each (to denote a list of that type) also leads to two equivalent types.
String is usually considered more idiomatic than [Char] when writing Haskell code, but it's not a big deal. (Even if you use String everywhere, the compiler might still use [Char] when reporting errors, so it's important to know about this equivalence.)
orderedCheck $ fst b : this is the part where I have a GHC error : "No instance for (Ord a) arising from a use of ‘orderedCheck’ ",I looked around and I can't understand what does it mean.
It's exactly as #Ismor said in the comments - but as I have a little more space in an answer I'll try to give a slightly longer, clearer explanation.
You are calling orderedCheck with the value fst b. And orderedCheck, by your own (correct) type signature, has type (Ord a) => [a] -> Bool. That means its argument must be a list, whose elements are of a type a which satisfies the constraint Ord a.
But you are using it on fst b in testReturn. b is the second argument to the function, which from its type signature must be of type ([a], [b]). This means fst b must be of type [a] - which is a list, so so far so good. But as just mentioned, that type a must have an instance of Ord. And unfortunately we can't guarantee that, because your type signature - [[Char]] -> ([a], [b]) -> Bool - allows both a and b to be absolutely anything. If this code compiled, that type signature would allow me to call that function as, for example, testReturn ["Example"] ([putStrLn "foo"], []) - but putStrLn "foo" has type IO (), which certainly has no Ord instance. (Unless you provide one in your code, which doesn't sound like a great idea - but even if you did, you could easily find another type with no Ord instance which would lead to the same problem.)
The only way to fix this is to fix the type signature of testReturn - it can't actually accept any type as a, because that type must have an Ord instance. So include that requirement, and you'll be fine:
testReturn :: (Ord a) => [[Char]] -> ([a], [b]) -> Bool
(As #MarkSeemann notes, that's exactly the signature GHC would have inferred for you if you'd left out any type signature. I certainly don't recommend leaving off type signatures for top-level functions, but if you're ever not sure of what the signature should be, this technique of leaving it out and then asking GHCi to infer it for you with :t is almost guaranteed to give you what you want.)
I heard somewhere else that the use of fst and snd may be a bit edgy (is it?), but I don't know how to do without it.
I'm not sure what "edgy" means in this context. It's certainly not "wrong", nor is it dangerous in the same way that head and tail are for lists - those functions will crash (at runtime) when given an empty list, whereas fst and snd will work fine for any 2-tuple (and if given a value that's not a 2-tuple, your code will fail to compile - so there is zero risk of a runtime crash).
However, it's not very elegant compared to pattern-matching, which here is rather like "destructuring" in other languages. I think most Haskellers would write your function like this instead, which is equivalent to your code and hopefully self-explanatory:
testReturn [] (b, _) = orderedCheck b
testReturn (a:as) (b, c)
| a == "sa" = testReturn as (saFunc b, c)
(Note that this function appears incomplete, and will crash if called with a non-empty first argument whose first element is anything other than "sa".)

Haskell type checking in code

Could you please show me how can I check if type of func is Tree or not, in code not in command page?
data Tree = Leaf Float | Gate [Char] Tree Tree deriving (Show, Eq, Ord)
func a = Leaf a
Well, there are a few answers, which zigzag in their answers to "is this possible".
You could ask ghci
ghci> :t func
func :: Float -> Tree
which tells you the type.
But you said in your comment that you are wanting to write
if func == Tree then 0 else 1
which is not possible. In particular, you can't write any function like
isTree :: a -> Bool
isTree x = if x :: Tree then True else False
because it would violate parametericity, which is a neat property that all polymorphic functions in Haskell have, which is explored in the paper Theorems for Free.
But you can write such a function with some simple generic mechanisms that have popped up; essentially, if you want to know the type of something at runtime, it needs to have a Typeable constraint (from the module Data.Typeable). Almost every type is Typeable -- we just use the constraint to indicate the violation of parametericity and to indicate to the compiler that it needs to pass runtime type information.
import Data.Typeable
import Data.Maybe (isJust)
data Tree = Leaf Float | ...
deriving (Typeable) -- we need Trees to be typeable for this to work
isTree :: (Typeable a) => a -> Bool
isTree x = isJust (cast x :: Maybe Tree)
But from my experience, you probably don't actually need to ask this question. In Haskell this question is a lot less necessary than in other languages. But I can't be sure unless I know what you are trying to accomplish by asking.
Here's how to determine what the type of a binding is in Haskell: take something like f a1 a2 a3 ... an = someExpression and turn it into f = \a1 -> \a2 -> \a3 -> ... \an -> someExpression. Then find the type of the expression on the right hand side.
To find the type of an expression, simply add a SomeType -> for each lambda, where SomeType is whatever the appropriate type of the bound variable is. Then use the known types in the remaining (lambda-less) expression to find its actual type.
For your example: func a = Leaf a turns into func = \a -> Leaf a. Now to find the type of \a -> Leaf a, we add a SomeType -> for the lambda, where SomeType is Float in this case. (because Leaf :: Float -> Tree, so if Leaf is applied to a, then a :: Float) This gives us Float -> ???
Now we find the type of the lambda-less expression Leaf (a :: Float), which is Tree because Leaf :: Float -> Tree. Now we can add substitute Tree for ??? to get Float -> Tree, the actual type of func.
As you can see, we did that all by just looking at the source code. This means that no matter what, func will always have that type, so there is no need to check whether or not it does. In fact, the compiler will throw out all information about the type of func when it compiles your code, and your code will still work properly because of type-checking. (The caveat to this (Typeable) is pointed out in the other answer)
TL;DR: Haskell is statically typed, so func always has the type Float -> Tree, so asking how to check whether that is true doesn't make sense.

Why does the type of a function change when it comes out of a monad in GHCi [duplicate]

This question already has an answer here:
Why does `peek` with a polymorphic Ptr return GHC.Prim.Any when used with a bind?
(1 answer)
Closed 6 years ago.
Something changes about the type of a function when it comes out of a monad.
In GHCI:
> :t map
map :: (a -> b) -> [a] -> [b]
> a <- return map
> :t a
a :: (GHC.Prim.Any -> GHC.Prim.Any)
-> [GHC.Prim.Any] -> [GHC.Prim.Any]
This change makes it hard to store the function in a higher rank type.
What is happening here and can I make it not happen?
(Also doesn't this violate one of the monad laws?)
First of all, there is no point in doing anything like a <- return map - its the same as let a = map, which works just fine. That said, I don't think that is your question...
Checking out the documentation of GHC.Prim.Any which gives us a big hint as to the role of Any.
It's also used to instantiate un-constrained type variables after type
checking. For example, length has type
length :: forall a. [a] -> Int
and the list datacon for the empty list has type
[] :: forall a. [a]
In order to compose these two terms as length [] a
type application is required, but there is no constraint on the
choice. In this situation GHC uses Any
(In terms of type application syntax, that looks like length #Any ([] #Any *))
The problem is that when GHCi sees x <- return map it tries to desugar it to return map >>= \x -> ... but the ... part is whatever you enter next into GHCi. Normally it would figure out what the type variables of map are going to be instantiated to (or whether they even should be instantiated to anything) based the ..., but since it has nothing there.
Another key point that #sepp2k points out is that x can't be given a polymorphic type because (>>=) expects (on its RHS) a rank-1 function, and that means its argument can't be polymorphic. (Loosening this condition pushes you straight into RankNTypes at which point you lose the ability to infer types reliably.)
Therefore, needing x to be monomorphic and having no information to help it instantiate the type variables that prevent x from being monomorphic, it defaults to using Any. That means that instead of (a -> b) -> [a] -> [b] you get (Any -> Any) -> [Any] -> [Any].

How to create a base case for a tuple in Haskell?

I have the following function:
encode_single :: (Eq a) => [a] -> (Int, a)
encode_single (x:xs) = (count xs + 1, x)
However, Haskell complained about needing a base case, but I don't know how to do this because of the generic a type.
Thanks!
First of all, what you received is only a warning, not an error. Haskell does not need the base case of the empty list, it just suggests it.
Partial functions are most often an anti-pattern in functional programming so it just points out something that may be wrong. You can avoid the warning in different ways.
The first one is to make your function safe: if it cannot always return a value it's return type shouldn't be (Int, a) but Maybe (Int, a), so you could do:
encode_single :: (Eq a) => [a] -> Maybe (Int, a)
encode_single [] = Nothing
encode_single (x:xs) = Just (count xs + 1, x)
Otherwise you'd have to return a meaningful value for the empty case (just returning undefined isn't better than not defining that case). It might be appropriate to do somethign like:
encode_single [] = (0, undefined)
However this assumes that any code that uses the result of encode_single will not evaluate the second element of the tuple if the first element is zero (note that if the list isn't empty the first element is always positive, so 0 can be used as a sentinel value).
This may or may not be the case. However one thing is sure: this is not compile-time safe so you may receive some run-time errors when calling such a function.
Simply enough: at the type you desire you cannot write a total function of that specification. You need to change the type.
You can either add a default a or indicate partiality using Maybe.
encode_single :: a -> [a] -> (Int, a)
encode_single :: [a] -> Maybe (Int, a)
if you cannot change the type signature, you can piggyback on head i.e.
encode_single :: [a] -> (Int, a)
encode_single a = (length a, head a)
obviously, empty list input is not handled properly.

Couldn't match expected type error

As a beginner, I was working on item number 3 of the Haskell 99 problems. The first code snippet is my solution. However, I cannot add the type declaration of [a] -> Int -> a.
It produces an error: Couldn't match type 'a' with 'Int'
--My Solution
--elementAt :: [a] -> Int -> a
elementAt xs num = head . reverse $ takeWhile (<num+1) xs
Meanwhile, one of the solution in the problem 3 works perfectly with the same output.
elementAt' :: [a] -> Int -> a
elementAt' list i = list !! (i - 1)
I've used the :type in the GHCI for the elementAt without the declaration and it shows:
elementAt :: (Num c, Ord c) => [c] -> c -> c
What is the difference of the two functions?
takeWhile (<num+1) xs says that you want to take elements at the front of the list xs while the element (not the index!) is less than num + 1. Since you're comparing num (which is an Int) with the list elements, the compiler infers that the list elements have to be Int as well, which contradicts your type declaration.
Without the type declaration, GHC infers that xs's elements and num have to be the same type (since you compare list elements with num). This type has to have an Ord instance (for the comparison) as well as a Num instance (because of the addition).
The type of takeWhile (< num + 1) is [Int] -> [Int].
However the type of xs is [a].
Essentially you are trying to apply a predicate Int -> Bool to elements of type a.
If you want to filter based on the position in the list, you first need to augment the input list with the position of each element. You can do this fairly easily with zip:
zip xs [1..]
You can then drop elements based on the value of the second element of the resulting list.

Resources