Instance of Show Haskell - haskell

I am doing my homework and I have a problem doing an instance of Show and I can't solve it, I tried a lot of things. I copy you the error and my code below.
My code:
type Height = Float
type Width = Float
type Radius = Float
data Rectangle = Rectangle Height Width
data Circle = Circle Radius
class Shape a where
area :: a -> Float
perimeter :: a -> Float
instance Shape Rectangle where
area (Rectangle h w) = h * w
perimeter (Rectangle b a) = (2*b) + (2*a)
instance Shape Circle where
area (Circle r) = pi * r**2
perimeter (Circle r) = 2*r*pi
type Volume = Float
volumePrism :: (Shape a) => a -> Height -> Volume
volumePrism base height = (area base) * height
surfacePrism ancho largo alto = (2*ancho*largo) + (2*largo*alto) + (2*ancho*alto)
instance Show a => Show (Shape a) where
show (Rectangle h w) = "Rectángulo de base " ++ w ++ "y altura " ++ h
And what the error says:
The first argument of 'Show' should have kind '*'

What you want to do is not possible. Shape is a typeclass, not a data type, so it has no constructors you can pattern match on. You could do something like
instance (Shape a) => Show a where
show shape = "Area: " ++ show (area shape) ++ " Perimeter: " ++ show (perimeter shape)
But this does not seem to be what you want. Instead, you should just define Show for each type individually:
instance Show Rectangle where
show (Rectangle h w) = "Rectangle with base " ++ show w ++ " and height " ++ show h
instance Show Circle where
show (Circle r) = "Circle with radius " ++ show r
The error about the "kind" can be quite cryptic for beginners (and sometimes experienced haskellers!), but in this case it's fairly straightforward. This does involve a new concept, though. In Haskell, you have values which have a type, such as functions, constants, even monadic actions. You can also talk about the "type of a type", what is known as the kind. There are a couple that you should know about and be comfortable using: * and Constraint. Most types you'll see only involve * and arrows between them. All "fully applied" data types should have kind *, it basically just means that it doesn't take any type parameters, so
> :kind Int
Int :: *
> :kind String
String :: *
> :kind IO ()
IO () :: *
> :kind Maybe Int
Maybe Int :: *
> :kind Either String Int
Either String Int :: *
However, you can have higher-kinded types as well:
> :kind IO -- Note lack of ()
IO :: * -> *
> :kind Maybe
Maybe :: * -> *
> :kind Either
Either :: * -> * -> *
Each * just represents another fully applied type. That last detail is important, it means you can't have Either IO Maybe, because that would be a nonsensical type. These can be higher order as well:
> import Control.Monad.State
> :kind StateT
StateT :: * -> (* -> *) -> * -> *
It's the same syntax as with function types, just without kind variables.
The other one you really need to know about is Constraint. This one is specially for typeclasses:
> :kind Show
Show :: * -> Constraint
> :kind Num
Num :: * -> Constraint
> :kind MonadState
MonadState :: * -> (* -> *) -> Constraint
And when fully applied they return a typeclass, rather than a datatype.
In case you're curious, there are GHC extensions that let you work with more complicated kinds, even allowing you to specify the kinds for a type or typeclass. There are some interesting tricks you can do with it, but these are generally considered more advanced features of the type system.

Shape is a typeclass, and you can’t make a typeclass an instance of another typeclass. (You can make all types that are an instance of a typeclass an instance of a different typeclass as well, but that doesn’t appear to be what you’re trying to do here.)
Rather, you appear to want to implement Show on Rectangle. So say that explicitly:
instance Show Rectangle where
show (Rectangle h w) = "Rectángulo de base " ++ w ++ "y altura " ++ h

Your instance declaration is not meaningful. Translated to English it would read as something like "for every a that is an instance of Show, a being an instance of Shape is an instance of Show" or something incomprehensible like that.
Just make Rectangle and Circle instances of Show and leave Shape out of it, unless you want to require that every instance of Shape must be an instance of Show, which is something that you need to put into the declaration of Shape.

Related

Haskell: Functor instance for newtype

To level set, here's a simple functor:
data Box a = Box a deriving (Show)
instance Functor Box where
fmap f (Box x) = Box (f x)
This allows us to operate "inside the box":
> fmap succ (Box 1)
Box 2
How do I achieve this same syntactic convenience with a newtype? Let's say I have the following:
newtype Width = Width { unWidth :: Int } deriving (Show)
newtype Height = Height { unHeight :: Int } deriving (Show)
This is a bit clunky:
> Width $ succ $ unWidth (Width 100)
Width {unWidth = 101}
This would be nice:
> fmap succ (Width 100) -- impossible?
Width {unWidth = 101}
Of course, I can't make Width or Height an instance of a Functor since neither has kind * -> *. Although, syntactically they feel no different than Box, and so it seems like it should be possible to operate on the underlying value without all of the manual wrapping and unwrapping.
Also, it isn't satisfying to create n functions like this because of the repetition with every new newtype:
fmapWidth :: (Int -> Int) -> Width -> Width
fmapHeight :: (Int -> Int) -> Height -> Height
How do I lift a function on Ints to be a function on Widths?
First note that newtype is no hurdle here – you can parameterise these just as well as data, and then you have an ordinary functor. Like
{-# LANGUAGE DeriveFunctor #-}
newtype WidthF a = Width { unWidth :: a } deriving (Show, Functor)
type Width = WidthF Int
I wouldn't consider that a good idea, though. Width shouldn't be a functor; it doesn't make sense to store non-number types in it.
One option as user2407038 suggests is to make it a “monomorphic functor”
import Data.MonoTraversable (MonoFunctor(..))
newtype Width = Width { unWidth :: Int } deriving (Show)
instance MonoFunctor Width where
omap f (Width w) = Width $ f w
That too doesn't seem sensible to me – if you map number operations thus in one generic way, then you might just as well give Width instances for Num etc. and use these directly. But then you hardly have better type-system guarantees than a simple
type Width = Int
which can easily be modified without any help, the flip side being that it can easily be mishandled without any type system safeguards.
Instead, I think what you want is probably this:
import Control.Lens
data Box = Box {
width, height :: Int }
widthInPx, heightInPx :: Lens' Box Int
widthInPx f (Box w h) = (`Box`h) <$> f w
heightInPx f (Box w h) = (Box w) <$> f h
Then you can do
> Box 3 4 & widthInPx %~ (*2)
Box 6 4
> Box 4 2 & heightInPx %~ succ
Box 4 3

Haskell -- Instance constraints bindings

I am learning Haskell programming language to understand functional programming paradigm.
I was trying to write following code
class Area shape where
area :: (Num n) => shape n -> n
data Quadrilateral t = Rectangle {length::t, width::t} | Square {side::t} deriving(Show)
data CircularShape t = Circle {radius::t} deriving(Show)
instance Area Quadrilateral where
area (Rectangle l w) = l * w
area (Square s ) = s * s
instance Area CircularShape where
area (Circle r) = pi * r * r
main = do
putStrLn . show . area $ Rectangle 10.0 20.0
putStrLn . show . area $ Square 10
putStrLn . show . area $ Circle 10.0
Here is the link for code
I am getting error below,
Error occurred
ERROR line 13 - Cannot justify constraints in instance member binding
*** Expression : area
*** Type : (Area CircularShape, Num a) => CircularShape a -> a
*** Given context : (Area CircularShape, Num a)
*** Constraints : Floating a
I am not able to understand the exact cause of this error. This code was working fine before adding the CircularShape data and it's corresponding instance of Area typeclass.
How I can solve this if I want to use both Quadrilateral and CircularShape ?
Since we are using different compiler, I show you the output of my error window.
box.hs|14 col 23 error| Could not deduce (Floating n) arising from a use of ‘pi’
|| from the context (Num n)
|| bound by the type signature for
|| area :: Num n => CircularShape n -> n
|| at /Users/evan/box.hs:14:5-8
|| Possible fix:
|| add (Floating n) to the context of
|| the type signature for area :: Num n => CircularShape n -> n
|| In the first argument of ‘(*)’, namely ‘pi’
|| In the first argument of ‘(*)’, namely ‘pi * r’
|| In the expression: pi * r * r
Basically, in your typeclass declaration, n is bound into Num which is too generic if you want to multiply it with pi, which is a floating point type.
Try changing Num into Floating
class Area shape where
area :: (Floating n) => shape n -> n
You might get a warning of something like "Defaulting to Double" which is because there are two floating types in haskell, (i.e Float and Double)
Change the type signature of area to
area:: (Floating n) => shape n -> n
Your code didn't work because multiplication with pi requires the type constraint Floating a
Also use print instead of putStrLn . show

Deriving Data.Complex in Haskell

I have code that looks a little like the following:
import Data.Complex
data Foo = N Number
| C ComplexNum
data Number = Int Integer
| Real Float
| Rational Rational
deriving Show
data ComplexNum = con1 (Complex Integer)
| con2 (Complex Float)
| con3 (Complex Rational)
deriving Show
But this seems like a bad way to do it. I would rather have
data Foo = N Number
| C (Complex Number)
and construct a ComplexNumber with something similar to ComplexNumber $ Real 0.0.
The question is how to make Complex Number possible. Since all of the types in Number have corresponding Complex instances, can I just add deriving Complex to Number?
The Haskell approach is to have different types for Complex Float and Complex Int rather than trying to unify them into one type. With type classes you can define all of these types at once:
data Complex a = C a a
instance Num a => Num (Complex a) where
(C x y) + (C u v) = C (x+u) (y+v)
(C x y) * (C u v) = C (x*u-y*v) (x*v+y*u)
fromInteger n = C (fromInteger n) 0
...
This at once defines Complex Int, Complex Double, Complex Rational, etc. Indeed it even defines Complex (Complex Int).
Note that this does not define how to add a Complex Int to a Complex Double. Addition (+) still has the type (+) :: a -> a -> a so you can only add a Complex Int to a Complex Int and a Complex Double to another Complex Double.
In order to add numbers of different types you have to explicitly convert them, e.g.:
addIntToComplex :: Int -> Complex Double -> Complex Double
addIntToComplex n z = z + fromIntegral n
Have a look at http://www.haskell.org/tutorial/numbers.html section 10.3 for more useful conversion functions between Haskell's numeric type classes.
Update:
In response to your comments, I would suggest focusing more on the operations and less on the types.
For example, consider this definition:
onethird = 1 / 3
This represents the generic "1/3" value in all number classes:
import Data.Ratio
main = do
putStrLn $ "as a Double: " ++ show (onethird :: Double)
putStrLn $ "as a Complex Double: " ++ show (onethird :: Complex Double)
putStrLn $ "as a Ratio Int: " ++ show (onethird :: Ratio Int)
putStrLn $ "as a Complex (Ratio Int): " ++ show (onethird :: Complex (Ratio Int))
...
In a sense Haskell let's the "user" decide what numeric type the expression should be evaluated as.
This doesn't appear to be legal Haskell code. You have three constructors of type ComplexNum all named Complex. Also, data types must begin with a capital letter, so foo isn't a valid type. It's hard to tell what you mean, but I'll take a stab:
If you have a type
data Complex a = (a,a)
you can keep your definition of Number and define foo as:
data Foo = N Number
| C (Complex Number)

Turtle Graphics as a Haskell Monad

I'm trying to implement turtle graphics in Haskell. The goal is to be able to write a function like this:
draw_something = do
forward 100
right 90
forward 100
...
and then have it produce a list of points (maybe with additional properties):
> draw_something (0,0) 0 -- start at (0,0) facing east (0 degrees)
[(0,0), (0,100), (-100,100), ...]
I have all this working in a 'normal' way, but I've failed to implement it as a Haskell Monad and use the do-notation. The basic code:
data State a = State (a, a) a -- (x,y), angle
deriving (Show, Eq)
initstate :: State Float
initstate = State (0.0,0.0) 0.0
-- constrain angles to 0 to 2*pi
fmod :: Float -> Float
fmod a
| a >= 2*pi = fmod (a-2*pi)
| a < 0 = fmod (a+2*pi)
| otherwise = a
forward :: Float -> State Float -> [State Float]
forward d (State (x,y) angle) = [State (x + d * (sin angle), y + d * (cos angle)) angle]
right :: Float -> State Float -> [State Float]
right d (State pos angle) = [State pos (fmod (angle+d))]
bind :: [State a] -> (State a -> [State a]) -> [State a]
bind xs f = xs ++ (f (head $ reverse xs))
ret :: State a -> [State a]
ret x = [x]
With this I can now write
> [initstate] `bind` (forward 100) `bind` (right (pi/2)) `bind` (forward 100)
[State (0.0,0.0) 0.0,State (0.0,100.0) 0.0,State (0.0,100.0) 1.5707964,State (100.0,99.99999) 1.5707964]
And get the expected result. However I can't make this an instance of Monad.
instance Monad [State] where
...
results in
`State' is not applied to enough type arguments
Expected kind `*', but `State' has kind `* -> *'
In the instance declaration for `Monad [State]'
And if I wrap the list in a new object
data StateList a = StateList [State a]
instance Monad StateList where
return x = StateList [x]
I get
Couldn't match type `a' with `State a'
`a' is a rigid type variable bound by
the type signature for return :: a -> StateList a
at logo.hs:38:9
In the expression: x
In the first argument of `StateList', namely `[x]'
In the expression: StateList [x]
I tried various other versions but I never got it to run as I'd like to. What am I doing wrong? What do I understand incorrectly?
The monad you're devising needs to have two type parameters. One for the saved trail (which will be fixed for a particular do sequence) and other for the results of computations.
You also need to think about how to compose two turtle-monadic values so that the binding operation is associative. For example,
right 90 >> (right 90 >> forward 100)
must be equal to
(right 90 >> right 90) >> forward 100
(and of course similarly for >>= etc.). This means that if you represent the turtle's history by a list of points, the binding operation most likely just cannot append the lists of points together; forward 100 alone will result in something like [(0,0),(100,0)] but when it's prepended with rotation, the saved points need to be rotated too.
I'd say that the simplest approach would be to use the Writer monad. But I wouldn't save the points, I'd save just the actions the turtle performs (so that we don't need to rotate the points when combining the values). Something like
data Action = Rotate Double | Forward Double
type TurtleMonad a = Writer [Action] a
(This also means that we don't need to track the current direction, it's contained in the actions.) Then each of your functions just writes its argument into the Writer. And at the end, you can extract the final list from it and make a simple function that converts all the actions into a list of points:
track :: [Action] -> [(Double,Double)]
Update: Instead of using [Action] it would be better to use Seq from Data.Sequence. It's also a monoid and concatenating two sequences is very fast, it's amortized complexity is O(log(min(n1,n2))), compared to O(n1) of (++). So the improved type would be
type TurtleMonad a = Writer (Seq Action) a

"Instance of Integral Float required" error

The file with following function:
type Point = (Float, Float)
type Circle = (Float, Float, Float)
getCircle :: Point -> Point -> Point -> Circle
getCircle (a, b) (c, d) (e, f) = (x, y, r)
where
x = ((a^2+b^2)*(f-d) + (c^2+d^2)*(b-f) + (e^2+f^2)*(d-b)) `div` (a*(f-d)+c*(b-f)+e*(d-b)) `div` 2
y = ((a^2+b^2)*(e-c) + (c^2+d^2)*(a-e) + (e^2+f^2)*(c-a)) `div` (b*(e-c)+d*(a-e)+f*(c-a)) `div` 2
r = sqrt ((a-x)^2 + (b-y)^2)
Throws an error when I try to load it to Hugs:
ERROR "/Users/ak/Desktop/1.hs":4 - Instance of Integral Float required for definition of getCircle
What's the essence of the problem and how can it be fixed?
Thanks.
You should use / in place of div -- 5 / 2, not 5 div 2. The reason is that haskell treats integral and floating point types differently -- they are instances of different typeclasses.
(/) is declared in typeclass Fractional, whereas div is declared in typeclass Integral. Those type classes have a common ancestor Num, but they do not have any subtyping relationships apart from that.
div is integer division and thus just works on Integral instanves. Simply use /

Resources