Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting between types in Haskell

Tags:

types

haskell

I'm trying to make a simple function to return a centered string of text in Haskell, but I'm having trouble just finding how much padding to insert either side. I have this:

center padLength string = round ((padLength - (length string)) / 2)

Which gives the following error:

No instance for (Fractional Int)
  arising from a use of '/'
Possible fix: add an instance declaration for (Fractional Int)
In the first argument of 'round', namely
  '((padLength - (length string)) / 2)'
In the expression: round ((padLength - (length string)) / 2)
In an equation for `center':
    center padLength string = round ((padLength - (length string)) / 2)

How can I (basically) convert from an Double (I think) to an Int?

like image 980
Dean Barnes Avatar asked Dec 18 '11 20:12

Dean Barnes


People also ask

Can you cast in Haskell?

And since Haskell is not object-oriented, there is no inheritance relationship that required any cast. There simply aren't meaningless object values that needed runtime-checking/casting. For expressing alternatives, you'll have to define a union type, a typeclass or use the Either type.

What does fromIntegral do in Haskell?

The workhorse for converting from integral types is fromIntegral , which will convert from any Integral type into any Num eric type (which includes Int , Integer , Rational , and Double ): fromIntegral :: (Num b, Integral a) => a -> b.

What is the difference between int and Integer in Haskell?

What's the difference between Integer and Int ? Integer can represent arbitrarily large integers, up to using all of the storage on your machine. Int can only represent integers in a finite range.


2 Answers

The problem is not that you can't convert a Double to an Int — round accomplishes that just fine — it's that you're trying to do division on an Int (padLength - length string). The error message is just telling you that Int is not an instance of Fractional, the typeclass for numbers that can be divided.

In general, you could use fromIntegral (padLength - length string) to turn it into a Double, but in this case, you can simply use integer division directly:

center padLength string = padLength - (length string) `div` 2

a `div` b is just a nicer way of writing div a b; you can use any function as a binary operator like this.

like image 193
ehird Avatar answered Sep 23 '22 01:09

ehird


You're trying to use fractional division / on operands of integral type, but that's not defined.

You should either convert the operands to Double before dividing (using fromIntegral), or use integral division div.

like image 24
JB. Avatar answered Sep 24 '22 01:09

JB.