Haskell : Show instance Ambiguity - haskell

I am trying to write a show instance to display well formed formula but after miming whole syntax I am still facing the same error as below.
Hugs> :load "C:\\Users\\Devil\\Desktop\\CASESTUDY1.hs"
ERROR file:.\CASESTUDY1.hs:15 - Ambiguous variable occurrence "show"
*** Could refer to: CASESTUDY1.show Hugs.Prelude.show
Below is the content of my .hs file include data type and related show instance .
module CASESTUDY1
where
data Wff = VAR String
| NEG Wff
| AND Wff Wff
| OR Wff Wff
| IMPL Wff Wff
instance Show Wff where
show (VAR x) = x
show (NEG x) = "~" ++ show(x)
show (AND x y) = "(" ++ show(x) ++ "^" ++ show(y) ++ ")"
show (OR x y) = "(" ++ show(x) ++ "v" ++ show(y) ++ ")"
show (IMPL x y) = "(" ++ show(x) ++ "-->" ++ show(y) ++ ")"

In haskell, whitespace is important. You need to indent the show's that belong to your instance of Show.
instance Show Wff where
show (VAR x) = show x
show (NEG x) = "~" ++ show x
show (AND x y) = "(" ++ show x ++ "^" ++ show y ++ ")"
show (OR x y) = "(" ++ show x ++ "v" ++ show y ++ ")"
show (IMPL x y) = "(" ++ show x ++ "-->" ++ show y ++ ")"
Also, you do not need parenthesis to pass the parameters to show. show(x) should be show x.
If you are learning haskell I recommend these exceptional resources:
Learn You a Haskell For Great Good
Real World Haskell

Related

Haskell occurring error regarding show instance

data Expr = Var Char | Not Expr | And Expr Expr | Or Expr Expr deriving (Eq, Ord)
instance Show Expr where
show (Var x) = [x]
show (Not (Var y)) = "~"++ show (Var y)
show (And (Var x) (Var y)) = show (Var x) ++ " ^ " ++ show (Var y)
show ((Or (Var x) (Var y))) = show (Var x) ++ " v " ++ show (Var y)
show (Not (Or (Var x) (Var y))) = "~(" ++ show (Or (Var x) (Var y)) ++ ")"
show (And (Var x) (And (Var y) (Var z))) = show (Var x) ++ " ^ " ++ "(" ++ show (And (Var y) (Var z)) ++ ")"
I`m not sure exactly why i get this error when i run:
>(Not (Not (Var 'a')))
*** Exception: (21,5)-(26,112): Non-exhaustive patterns in function show
Can anyone help me.
An And can also contain another And, so for example And (And (Var 'x') (Var 'y')) (Var 'z'). In your Show instance you always assume that the parameters are Vars, that is not necessary.
You can implement the Show instance as:
instance Show Expr where
show (Var x) = [x]
show (Not x) = "~ ("++ show x ++ ")"
show (And x y) = "(" ++ show x ++ " ^ " ++ show y ++ ")"
show (Or x y) = "(" ++ show x ++ " v " ++ show y ++ ")"
This will introduce a lot of parenthesis. Therefore it is better to work with a precedence parameter. In fact the Show instance already has support for this: you can work with showsPrec :: Int -> a -> String -> String. Here the Int parameter is the operator precedence of the outer context, and the first String parameter is the string that needs to be appended at the end: that is done for performance reasons.
We thus can implement this as:
instance Show Expr where
showsPrec n (Var x) = (x :)
showsPrec n (Not x) = showParen (n > 9) ( ('~' :) . showsPrec 10 x)
showsPrec n (And x y) = showParen (n > 8) ((showsPrec 9 x) . (" ^ " ++) . showsPrec 9 y)
showsPrec n (Or x y) = showParen (n > 7) ((showsPrec 8 x) . (" v " ++) . showsPrec 8 y)
Here we will show parenthesis for not if the outer countext has a precedence higher than 9, and call the showPrec with a precence 10 such that the showPrec inside will not print extra parenthesis, unless it has a precedence of 10 or higher. The same applies for the other functions.
This thus means that we can print an expression with parenthesis like:
ghci> show (Not (And (Or (Not (Var 'x')) (Var 'y')) (Var 'z')))
"~((~x v y) ^ z)"
Here the And … … will thus print parenthesis since it is called with a precedence of nine, and the threshold is 8 to print parenthesis. But there are no brackets for around ~x, since the threshold is lower than 10.
Instead of hard-coding lots of deep expressions, you should just pattern match on the topmost constructors and then recurse down.
instance Show Expr where
show (Var v) = [v]
show (Not x) = "Not ("++show x++")"
show (And x y) = "(" ++ show x ++ ") ∧ (" ++ ...
show (Or x y) = ...
Remember to implement the ∧ and ∨ operators if you mention them in the show results.
infixr 3 ∧
(∧) :: Expr -> Expr -> Expr
(∧) = And
Actually it is preferred to not implement show when defining recursive-data Show instances, instead implement showsPrec which has a more sophisticated way of adding parentheses as needed.

Why does my gcd function in haskell only work when it returns type Writer [String] Int and not Writer String Int?

The following code does not work:
gcd' :: Int -> Int -> Writer String Int
gcd' a b
| b == 0 = do
tell "gcd " ++ show a ++ " " ++ show b ++ " \n"
return a
| otherwise = do
tell "gcd " ++ show a ++ " " ++ show b ++ " \n"
gcd' b (a `mod` b)
When I changed the code to this, it now works:
gcd' :: Int -> Int -> Writer [String] Int
gcd' a b
| b == 0 = do
tell ["gcd " ++ show a ++ " " ++ show b ++ " \n"]
return a
| otherwise = do
tell ["gcd " ++ show a ++ " " ++ show b ++ " \n"]
gcd' b (a `mod` b)
Although I'd now have to concatenate the list of strings.
I don't understand why my original code doesn't work. Surely, my original code should concatenate the strings from each step to give an overall log. But instead, it gives me the following error message:
gcdLogger.hs:6:6: error:
• Couldn't match type ‘[]’
with ‘WriterT String Data.Functor.Identity.Identity’
Expected type: WriterT String Data.Functor.Identity.Identity ()
Actual type: [()]
• In a stmt of a 'do' block:
tell "gcd " ++ show a ++ " " ++ show b ++ " /n"
In the expression:
do tell "gcd " ++ show a ++ " " ++ show b ++ " /n"
return a
In an equation for ‘gcd'’:
gcd' a b
| b == 0
= do tell "gcd " ++ show a ++ " " ++ show b ++ " /n"
return a
| otherwise
= do tell "gcd " ++ show a ++ " " ++ show b ++ " /n"
gcd' b (a `mod` b)
Your first attempt does not work since function application takes precedence over operators. So it is parsed as:
(tell "gcd ") ++ (show a) ++ " " ++ (show b) ++ "\n "
In the second attempt, you wrap the strings each time in a singleton list, so then you write a list of Strings (well all these lists contain one string, but that still does not make these Strings).
You can solve the problem by adding brackets here:
gcd' :: Int -> Int -> Writer String Int
gcd' a b = do
tell ("gcd " ++ show a ++ " " ++ show b ++ " \n")
if b == 0 then
return a
else
gcd' b (a `mod` b)
For example:
Prelude Control.Monad.Trans.Writer.CPS> runWriter (gcd' 15 5)
(5,"gcd 15 5 \ngcd 5 0 \n")
Note that for debugging purposes, it more convenient for you to use trace :: String -> a -> a instead of a Writer, as it will more nicely do what you want.

* Couldn't match type `(Float, Float)' with `[Point]'

CODE
type Point = (Float,Float)
type Candidate = (Point,Point,[Point],Float)
print_list :: [[Point]] -> String
print_list [] = ""
print_list [x:xs] = show x ++ "," ++ print_list(xs)
candidate_to_string :: Candidate -> String
candidate_to_string (a, x, y:ys, z) = "Start point: " ++ show a ++
"\nSupporting Points: " ++ print_list(y:ys) ++ "\nEnd Point: " ++ show x
++ "\nTime: " ++ show z
ERROR MESSAGE
C:\\Users\conor\Desktop\haskellcoursework.hs:47:50: error:
* Couldn't match type `(Float, Float)' with `[Point]'
Expected type: [[Point]]
Actual type: [Point]
* In the first argument of `print_list', namely `(xs)'
In the second argument of `(++)', namely `print_list (xs)'
In the second argument of `(++)', namely `"," ++ print_list (xs)'
|
47 | print_list [x:xs] = show x ++ "," ++ print_list(xs)
| ^^
C:\\Users\conor\Desktop\haskellcoursework.hs:50:107: error:
* Couldn't match type `(Float, Float)' with `[Point]'
Expected type: [[Point]]
Actual type: [Point]
* In the first argument of `print_list', namely `(y : ys)'
In the first argument of `(++)', namely `print_list (y : ys)'
In the second argument of `(++)', namely
`print_list (y : ys)
++ "\nEnd Point: " ++ show x ++ "\nTime: " ++ show z'
|
50 | candidate_to_string (a, x, y:ys, z) = "Start point: " ++ show a ++
"\nSupporting Points: " ++ print_list(y:ys) ++ "\nEnd Point: " ++ show x ++
"\nTime: " ++ show z ^^^^
|
The signatures I have used are specified for me. My task is to write a function candidate_to_string :: Candidate -> String which creates a string representation
of a candidate. Each Point is written in its own line starting with the start point, followed by
all supporting points and ending with the end point. The time is printed in an extra line consisting
of the string “Time: ” and the value.
print_list requires a [[Point]] -- a list of lists of points
print_list :: [[Point]] -> String
-- ^^^^^^^^^ --
but here you pass it a [Point] a list of points. Hence, a type error arises:
candidate_to_string :: Candidate -> String
candidate_to_string (a, x, y:ys, z) =
... print_list(y:ys) ...
-- ^^^^^^ this is a [Point]
The mistake is that print_list should instead be [Point] -> String. More in detail,
print_list [x:xs] = show x ++ "," ++ print_list(xs)
is wrong, since [x:xs] is a list containing only one element, namely the list x:xs. You don't want a list-of-lists here, so simply use something like
print_list :: [Point] -> String
print_list [] = ""
print_list [x] = show x -- we don't want a trailing comma here
print_list (x:xs) = show x ++ "," ++ print_list xs

Instance of Show for lambda-abstraction ADT

So, I have already defined the lambda data type as such:
data LExpr
= Variable String -- variable
| Apply LExpr LExpr -- function application
| Lambda String LExpr -- Lambda abstraction
deriving (Eq, Show)
Now I want to implement an instance of Show myself. I have already the function show' which does most of the work, but without using instances:
show' :: LExpr -> String
show' (Variable a) = a
show' (Apply e1 e2) = "(" ++ show' e1 ++ " " ++ show' e2 ++ ")"
show' (Lambda x e) = "(λ " ++ x ++ ". " ++ show' e ++ ")"
How I can implement it, to get the following output without using explicitly the show' function:
Main> (Apply (Lambda "x" (Apply (Variable "x") (Variable "y"))) (Variable "z"))
((λ x. x y) y)
Add an instance declaration for the Show class.
instance Show LExpr where
show = show'
And remove the deriving(Show) part
data LExpr
= Variable String -- variable
| Apply LExpr LExpr -- function application
| Lambda String LExpr -- Lambda abstraction
deriving (Eq)

Class Instances and ambiguous occurence in Haskell

Here is the code:
data Tree t = NilT
| Node t (Tree t) (Tree t)
instance Show (Tree t) where
show NilT = ""
show Node t l r = (show t) ++ ", " ++ (show l) ++ ", " ++ (show r)
how to use "show" in "t show" with the default setting and use "show" with the tree data with the definition given by myself?
In order to use show t, you must add the constraint Show t to your instance definition.
instance Show t => Show (Tree t) where
show NilT = ""
show (Node t l r) = show t ++ ", " ++ show l ++ ", " ++ show r
You were also missing parenthesis around your pattern Node t l r, and I removed the parenthesis around the calls to show, as they were redundant since function application already has the highest precedence.
Just a side note: There is a function Data.List.intersperse for putting a value between list elements.
show (Node t l r) = concat $ intersperse ", " [show t, show l, show r]
Or shorter, as hammar pointed out:
show (Node t l r) = intercalate ", " [show t, show l, show r]
Unfortunately you can't write map show [t, l, r], as the list elements need to have a unique type.

Resources