'Cannot find "show" function' error when parameter is instance of Show - haskell

The following error is triggered:
ERROR - Cannot find "show" function for:
*** Expression : debugFunction getDebugTree
*** Of type : Tree (Tree Int) -> Bool
when running debugFunction getDebugTree
data Tree a = Empty | Node a (Tree a) (Tree a) deriving (Eq, Show)
getDebugTree :: Tree Int
getDebugTree = (Node 1 (Empty) (Node 2 Empty Empty))
debugFunction :: Show a => a -> Tree a -> Bool
debugFunction _ _ = True
I've read that
reverse []
ERROR: Cannot find "show" function for:
* expression : reverse []
* of type : [a]
The top-level system for Hugs can only print values which belong to a
type which can be shown, that is a type which belongs to the Show
class. Now, the list type is an instance of Show, so what is wrong
with reverse [] (which evaluates to [])? The problem is that the type
of [] is polymorphic: [] :: [a] for all a. Not knowing a Hugs refuses
to print a value of type [a]. Note that this behaviour applies to all
polymorphic values. Given the definition
data Tree a = Empty | Node (Tree a) a (Tree a)
we have, on evaluating
Empty
the error message
ERROR: Cannot find "show" function for:
* expression : Empty
* of type : Tree a
Functions can be shown, but not very helpfully; printing any function
results in
<< function>>
As far as I understand Hugs doesn't know a so it refuses to print it (even though I'm printing a Bool?) so I've tried to make a be an instance of Show, but it still doesn't work, what's the problem here?

Look at the type of debugFunction.
debugFunction :: Show a => a -> Tree a -> Bool
debugFunction expects two arguments, the second of which is a Tree a. You're only passing it one. The type checker sees that you're passing a Tree Int as the first argument and infers a ~ Tree Int. So debugFunction getDebugTree is a function waiting for a second argument of type Tree (Tree Int).
debugFunction getDebugTree :: Tree (Tree Int) -> Bool
I suspect you intended to use getDebugTree as the second argument to debugFunction, which means you need to come up with an Int to use as the first one.
debugFunction 0 getDebugTree :: Bool
The error message about the missing Show instance comes from the REPL itself. It's attempting to print out the result of debugFunction getDebugTree, but it can't because functions can't be shown.

Related

How to Access Fields of Custom Data Types without Record Syntax in Haskell?

I'd like to understand how to access fields of custom data types without using the record syntax. In LYAH it is proposed to do it like this:
-- Example
data Person = Subject String String Int Float String String deriving (Show)
guy = Subject "Buddy" "Finklestein" 43 184.2 "526-2928" "Chocolate"
firstName :: Person -> String
firstName (Subject firstname _ _ _ _ _) = firstname
I tried applying this way of accessing data by getting the value of a node of a BST:
data Tree a = EmptyTree | Node a (Tree a) (Tree a) deriving (Show, Read, Eq)
singleton :: a -> Tree a
singleton x = Node x EmptyTree EmptyTree
treeInsert :: (Ord a) => a -> Tree a -> Tree a
treeInsert x EmptyTree = singleton x
treeInsert x (Node a left right)
| x == a = Node x left right
| x < a = Node a (treeInsert x left) right
| x > a = Node a left (treeInsert x right)
getValue :: Tree -> a
getValue (Node a _ _) = a
But I got the following error:
Could someone explain how to access the field correctly without using the record syntax and what the error message means? Please note that I'm a beginner in Haskell. My purpose is to understand why this particular case throws an error and how to do it it correctly. I'm not asking this to be pointed to more convenient ways of accessing fields (like the record syntax). If someone asked a similar question before: Sorry! I really tried finding an answer here but could not. Any help is appreciated!
You forgot to add the type parameter to Tree in your function's type signature
getValue :: Tree -> a
should be
getValue :: Tree a -> a
Expecting one more argument to `Tree'
means that Tree in the type signature is expecting a type argument, but wasn't provided one
Expected a type, but Tree has a kind `* -> *'
Tree a is a type, but Tree isn't (?) because it is expecting a type argument.
A kind is like a type signature for a type.
A kind of * means the type constructor does not expect any type of argument.
data Tree = EmptyTree | Tree Int Tree Tree
has a kind of *
It is like the type signature of a no-argument function (technically this is not really called a function, I think)
f :: Tree Int
f = Node 0 EmptyTree EmptyTree
A kind of * -> * means the type constructor expects an argument.
Your Tree type has a kind of * -> *, because it takes one type argument, the a on the left hand side of =.
A kind of * -> * is sort of like a function that takes one argument:
f :: Int -> Tree Int
f x = Node x EmptyTree EmptyTree

What is the resolution to this "No Instance" error?

I have created new type describing Binary Tree
data BinTree a = Null | Num a (BinTree a) (BinTree a)
deriving (Show)
And have created the following function:
treehandle :: BinTree a -> Bool
treehandle a = True
to check at least inputing values.
When I input value Null, program outputs result successfully, but I can't input binary tree. I try thus:
treehandle (5 (Null) (Null))
but obtain:
<interactive>:66:13:
No instance for (Num (BinTree a1 -> BinTree a2 -> BinTree a0))
(maybe you haven't applied enough arguments to a function?)
arising from the literal ‘5’
In the expression: 5
In the first argument of ‘treehandle’, namely ‘(5 (Null) (Null))’
In the expression: treehandle (5 (Null) (Null))
Why?
You forgot the value constructor's name
treehandle (Num 5 (Null) (Null))
I would find a different naming for the data constructors if I was you. Num is also the name of a type class, this can be very confusing when looking at error messages.
Also deriving Show is not correctly indented, and you forgot the data constructor in treehandle (5 (Null) (Null)). Here is a working version.
data BinTree a = Leaf | Node a (BinTree a) (BinTree a) deriving Show
treehandle :: BinTree a -> Bool
treehandle _ = True
test = treehandle $ Node 5 Leaf Leaf
treehandle wants a value of type BinTree a and all you gave it was an Int and two empty BinTree's, it actually tried to apply the Int with the two empty BinTree's and failed. You have to make a Node to get a single BinTree a which you can pass to treehandle
I thank for your replies. I appreciate it. Haskell is "wild" language being mix of Lisp and Prolog. Gradually I begin to get used to it. I would share with my results. So, that's BinTree declaration:
data BinTree a = Leaf | Val a (BinTree a) (BinTree a)
deriving (Show)
It resembles on Prolog unification algorithm - I mean about definition of "reverse" as below:
reverse :: BinTree a -> BinTree a
reverse (Val a1 (a2) (a3)) = (Val a1 (reverse a3) (reverse a2))
reverse Leaf = Leaf
It works!

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.

Haskell getting to the tuple

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.

How can I build a recursive tree with concrete data types in Haskell?

I'd like to build a tree in Haskell where each node has a concrete data type. Ultimately I want to build and use my own, more complicated types, but I can't quite figure out how to get the toy example below to work.
I'd like to create a tree of Integers, starting with a large value at the trunk, getting smaller as you traverse down to the leaves.
data Tree x = Empty | Node x (Tree x) (Tree x) deriving (Show, Read, Eq)
copyBox :: Int -> Tree x
copyBox x
| x <= 0 = Node x Empty Empty
| x > 0 = Node x (copyBox (x-1)) (copyBox (x-1))
I would expect to be able to build a small tree like this:
let newtree = copyBox 3
ghci throws an error "Couldn't match expected type 'x' with actual type 'Int'" at line 5.
If I replace the function declaration above with the more general version below, there is no problem:
copyBox :: (Ord x, Num x) => x -> Tree x
Why isn't the type of x just "Int" in both cases?
copyBox :: Int -> Tree x promises to return a Tree of any type at all, at the caller's whim. So I can write copyBox 5 :: Tree String, which is a legal call based on your type signature. But of course this will fail: you're putting x in the Nodes; and you're trying to subtract 1 from it, which only works if it's a numeric type; and you're comparing it to 0, which only works if it's an ordered type...
You probably just intend copyBox :: Int -> Tree Int, since you are clearly only building a Tree with Int values in it.

Resources