My code, where n = 4:
f n = map (4/) [1..n]
main = do
n <- getLine
print(f (product(map read $ words n :: [Int])))
If I use in terminal map (4/) [1..n] I get a right answer: [4.0,2.0,1.3333333333333333,1.0].
But in my program it's doesn't work, error message is: No instance for (Fractional Int) arising from a use off'`
Where is my mistake?
Your n is an Int which isn't a Fractional type. Those are the ones that support division using the / operator. You can either replace / with div to get integer division (truncates to whole numbers) or you can add fromIntegral to convert the n to the correct type.
Your code should look something like
f n = map (4/) [1..fromIntegral n]
To clarify a bit more: Your function f ultimately does division on the parameter that's given to it. This leads the type inference engine to determine that those parameters should be Fractional types. Then you use that function in your main you explicitly give it an Int.
That's why the error says "You gave me an Int. There's no instance for Fractional Int (read as, 'Int isn't a Fractional type') and I need it to be because you're passing an Int into something that requires that instance."
Related
I'm currenlty learning Haskell and have questions regarding this example found in Joachim Breitner's online course CIS194:
import Text.Read
main = putStrLn "Hello World. Please enter a number:" >>
getLine >>= \s ->
case readMaybe s of -- why not `readMaybe s :: Maybe Int` ?!
Just n -> let m = n + 1 in
putStrLn (show m)
Nothing -> putStrLn "That’s not a number! Try again"
The code does exactly what expected, that is it returns an integer +1 if the input is an integer and it returns "That’s not a number! Try again" otherwise (e.g. if the input is a Double).
I don't understand why readMaybe s only returns Just n if n is of type Int. The type of readMaybe is readMaybe :: Read a => String -> Maybe a and therefore I thought it would only work if the line read instead:
case readMaybe s :: Maybe Int of
In fact if I just prompt > readMaybe "3" in ghci, it returns Nothing, whereas > readMaybe "3" :: Maybe Int returns Just 3.
To sum up, my question is the following: how does the compiler now that s is parsed to an Int and not something else (e.g. Double) without the use of :: Maybe Int? Why does it not return Nothing everytime ?
I hope my question was clear enough, thanks a lot for your help.
TL;DR: The context of readMaybe s tells us that it's a Num a => Maybe a, defaulting makes it a Maybe Integer.
We have to look at all places where the result of readMaybe is used to determine its type.
We have
Nothing, which doesn't tell us aynthing about a
Just n, and n is used in the context m = n + 1.
Since m = n + 1, we now know that n's type must be an instance of Num, since (+) :: Num a => a -> a -> a and 1 :: Num a => a. At this point the type isn't clear, therefore it gets defaulted:
4.3.4 Ambiguous Types, and Defaults for Overloaded Numeric Operations
topdecl -> default (type1 , ... , typen) (n>=0)
A problem inherent with Haskell -style overloading is the possibility of an ambiguous type. For example, using the read and show functions defined in Chapter 10, and supposing that just Int and Bool are members of Read and Show, then the expression
let x = read "..." in show x -- invalid
is ambiguous, because the types for show and read,
show :: forall a. Show a =>a ->String
read :: forall a. Read a =>String ->a
could be satisfied by instantiating a as either Int in both cases, or Bool. Such expressions are considered ill-typed, a static error.
We say that an expression e has an ambiguous type if, in its type forall u. cx =>t, there is a type variable u in u that occurs in cx but not in t. Such types are invalid.
The defaults defined in the Haskell report are default (Integer, Double), e.g. GHC tries Integer first, and if that doesn't work it tries to use Double.
Since Integer is a valid type in the context m = n + 1, we have m :: Integer, therefore n :: Integer, and at last readMaybe s :: Maybe Integer.
If you want to disable defaults, use default () and you'll be greeted by ambiguous types errors, just as you expected.
There indeed some underlying magic, due to how type inference works.
Here's a simpler example, run inside GHCi:
> print (1 :: Integer)
1
> print (1 :: Float)
1.0
Prelude> print 1
1
In the last line, 1 is a polymorphic value of type Num a => a, i.e. a value inside any numeric type like Integer and Float. If we consider that value inside type Integer, we print it as "1". If we consider it as a Float, we print it as "1.0". Other numeric types may even have different print formats.
Still, GHCi in the last line decides that 1 is an Integer. Why?
Well, it turns out that the code is ambiguous: after all 1 could be printed in different ways! Haskell in such cases raises an error, due to the ambiguity. However, it makes an exception for numeric types (those inc lass Num), to be more convenient to program. Concretely, when a numeric type is not precisely determined by the code, Haskell uses its defaulting rules, which specify which numeric types should be used.
GHC can warn when defaulting happens, if wanted.
Further, the types are propagated. If we evaluate
case readMaybe s of
Just x -> let z = x + length ['a','z']
in ...
GHC knows that length returns an Int. Also, (+) operates only on arguments of the same type, hence x has to be an Int as well. This in turns implies that the call readMaybe s has to return Maybe Int. Hence, the right Read instance for Ints is chosen.
Note how this information is propagated backwards by the type inference engine, so that the programmer does not have to add type annotations which can be deduced from the rest of the code. It happens very frequently in Haskell.
One can always be explicit, as in
readMaybe s :: Maybe Int
-- or, with extensions on, one can mention the variable part of the type, only
readMaybe s # Int
If you prefer, feel free to add such annotations. Sometimes, they make the code more readable since they document your intent. Whoever reads the code, can immediately spot which Read instance is being used here without looking at the context.
I'm trying to work a problem where I need to calculate the "small" divisors of an integer. I'm just bruteforcing through all numbers up to the square root of the given number, so to get the divisors of 10 I'd write:
[k|k<-[1...floor(sqrt 10)],rem 10 k<1]
This seems to work well. But as soon as I plug this in a function
f n=[k|k<-[1...floor(sqrt n)],rem n k<1]
And actually call this function, I do get an error
f 10
No instance for (Floating t0) arising from a use of `it'
The type variable `t0' is ambiguous
Note: there are several potential instances:
instance Floating Double -- Defined in `GHC.Float'
instance Floating Float -- Defined in `GHC.Float'
In the first argument of `print', namely `it'
In a stmt of an interactive GHCi command: print it
As far as I undrestand the actual print function that prints the result to the console is causing trouble, but I cannot find out what is wrong. It says the type is ambiguous, but the function can clearly only return a list of integers. Then again I checked the type, and it the (inferred) type of f is
f :: (Floating t, Integral t, RealFrac t) => t -> [t]
I can understand that fshould be able to accept any real numerical value, but can anyone explain why the return type should be anything else than Integral or int?
[k|k<-[1...floor(sqrt 10)],rem 10 k<1]
this works because the first 10 is not the same as the latter one - to see this, we need the type signature of your functions:
sqrt :: Floating a => a -> a
rem :: Integral a => a -> a -> a
so the first one means that it works for stuff that have a floating point representation - a.k.a. Float, Double ..., and the second one works for Int, Integer (bigint), Word8 (unsigned 8bit integers)...
so for the 10 in sqrt 10 the compiler says - ahh this is a floating point number, null problemo, and for the 10 in rem 10 k, ahh this is an integer like number, null problemo as well.
But when you bundle them up in a function - you are saying n has to be a floating point and an integral number, the compiler knows no such thing and - complains.
So what do we do to fix that (and a side note ranges in haskell are indicated by .. not ...!). So let us start by taking a concrete solution and generalize it.
f :: Int -> [Int]
f n = [k|k <- [1..n'],rem n k < 1]
where n' = floor $ sqrt $ fromIntegral n
the neccessary part was converting the Int to a floating point number. But if you are putting that in a library all your users need to stick with using Int which is okay, but far from ideal - so how do we generalize (as promised)? We use GHCi to do that for us, using a lazy language we ourselves tend to be lazy as well.
We start by commenting out the type-signature
-- f :: Int -> [Int]
f n = [k|k <- [1..n'],rem n k < 1]
where n' = floor $ sqrt $ fromIntegral n
$> ghci MyLib.hs
....
MyLib > :type f
f :: Integral a => a -> [a]
then we can take this and put it into the library and if someone worked with Word8 or Integer that would work as well.
Another solution would be to use rem (floor n) k < 1 and have
f :: Floating a, Integral b => a -> [b]
as the type, but that would be kind of awkward.
I'm doing problem 20 on Project Euler - finding the sum of the digits of 100! (factorial, not enthusiasm).
Here is the program I wrote:
import Data.Char
main = print $ sumOfDigits (product [1..100])
sumOfDigits :: Int -> Int
sumOfDigits n = sum $ map digitToInt (show n)
I compiled it with ghc -o p20 p20.hs and executed it, getting only 0 on my command line.
Puzzled, I invoked ghci and ran the following line:
sum $ map Data.Char.digitToInt (show (product [1..100]))
This returned the correct answer. Why didn't the compiled version work?
The reason is the type signature
sumOfDigits :: Int -> Int
sumOfDigits n = sum $ map digitToInt (show n)
use
sumOfDigits :: Integer -> Int
and you will get the same thing as in GHCi (what you want).
Int is the type for machine word sized "ints" while, Integer is the type for mathematically correct, arbitrary precision Integers.
if you type
:t product [1..100]
into GHCi you will get something like
product [1..100] :: (Enum a, Num a) => a
that is, for ANY type that has instances of the Enum and Num type classes, product [1..100] could be a value of that type
product [1..100] :: Integer
should return 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000 which is far bigger than your machine is likely to be able to represent as a word on your machine. Probably, because of roll over
product [1..100] :: Int
will return 0
given this, you might think
sum $ map Data.Char.digitToInt (show (product [1..100]))
would not type check, because it has multiple possible incompatible interpretations. But, in order to be usable as a calculator, Haskell defaults to using Integer in situations like this, thus explaining your behavior.
For the same reason, if you had NOT given sumOfDigits an explicit type signature it would have done what you want, since the most general type is
sumOfDigits :: Show a => a -> Int
I'm learning Haskell, and am implementing an algorithm for a class. It works fine, but a requirement of the class is that I keep a count of the total number of times I multiply or add two numbers. This is what I would use a global variable for in other languages, and my understanding is that it's anathema to Haskell.
One option is to just have each function return this data along with its actual result. But that doesn't seem fun.
Here's what I was thinking: suppose I have some function f :: Double -> Double. Could I create a data type (Double, IO) then use a functor to define multiplication across a (Double, IO) to do the multiplication and write something to IO. Then I could pass my new data into my functions just fine.
Does this make any sense? Is there an easier way to do this?
EDIT: To be more clear, in an OO language I would declare a class which inherits from Double and then override the * operation. This would allow me to not have to rewrite the type signature of my functions. I'm wondering if there's some way to do this in Haskell.
Specifically, if I define f :: Double -> Double then I should be able to make a functor :: (Double -> Double) -> (DoubleM -> DoubleM) right? Then I can keep my functions the same as they are now.
Actually, your first idea (return the counts with each value) is not a bad one, and can be expressed more abstractly by the Writer monad (in Control.Monad.Writer from the mtl package or Control.Monad.Trans.Writer from the transformers package). Essentially, the writer monad allows each computation to have an associated "output", which can be anything as long as it's an instance of Monoid - a class which defines:
The empty output (mempty), which is the output assigned to 'return'
An associative function (`mappend') that combines outputs, which is used when sequencing operations
In this case, your output is a count of operations, the 'empty' value is zero, and the combining operation is addition. For example, if you're tracking operations separately:
data Counts = Counts { additions: Int, multiplications: Int }
Make that type an instance of Monoid (which is in the module Data.Monoid), and define your operations as something like:
add :: Num a => a -> a -> Writer Counts a
add x y = do
tell (Counts {additions = 1, multiplications = 0})
return (x + y)
The writer monad, together with your Monoid instance, then takes care of propagating all the 'tells' to the top level. If you wanted, you could even implement a Num instance for Num a => Writer Counts a (or, preferably, for a newtype so you're not creating an orphan instance), so that you can just use the normal numerical operators.
Here is an example of using Writer for this purpose:
import Control.Monad.Writer
import Data.Monoid
import Control.Applicative -- only for the <$> spelling of fmap
type OpCountM = Writer (Sum Int)
add :: (Num a) => a -> a -> OpCountM a
add x y = tell (Sum 1) >> return (x+y)
mul :: (Num a) => a -> a -> OpCountM a
mul x y = tell (Sum 1) >> return (x*y)
-- and a computation
fib :: Int -> OpCountM Int
fib 0 = return 0
fib 1 = return 1
fib n = do
n1 <- add n (-1)
n2 <- add n (-2)
fibn1 <- fib n1
fibn2 <- fib n2
add fibn1 fibn2
main = print (result, opcount)
where
(result, opcount) = runWriter (fib 10)
That definition of fib is pretty long and ugly... monadifying can be a pain. It can be made more concise with applicative notation:
fib 0 = return 0
fib 1 = return 1
fib n = join (fib <$> add n (-1) <*> add n (-2))
But admittedly more opaque for a beginner. I wouldn't recommend that way until you are pretty comfortable with the idioms of Haskell.
What level of Haskell are you learning? There are probably two reasonable answers: have each function return its counts along with its return value like you suggested, or (more advanced) use a monad such as State to keep the counts in the background. You could also write a special-purpose monad to keep the counts; I do not know if that is what your professor intended. Using IO for mutable variables is not the elegant way to solve the problem, and is not necessary for what you need.
Another solution, apart from returning a tuple or using the state monad explicitly, might be to wrap it up in a data type. Something like:
data OperationCountNum = OperationCountNum Int Double deriving (Show,Eq)
instance Num OperationCountNum where
...insert appropriate definitions here
The class Num defines functions on numbers, so you can define the functions +, * etc on your OperationCountNum type in such a way that they keep track of the number of operations required to produce each number.
That way, counting the operations would be hidden and you can use the normal +, * etc operations. You just need to wrap your numbers up in the OperationCountNum type at the start and then extract them at the end.
In the real world, this probably isn't how you'd do it, but it has the advantage of making the code easier to read (no explicit detupling and tupling) and being fairly easy to understand.
I'd like to divide two Int values in Haskell and obtain the result as a Float. I tried doing it like this:
foo :: Int -> Int -> Float
foo a b = fromRational $ a % b
but GHC (version 6.12.1) tells me "Couldn't match expected type 'Integer' against inferred type 'Int'" regarding the a in the expression.
I understand why: the fromRational call requires (%) to produce a Ratio Integer, so the operands need to be of type Integer rather than Int. But the values I'm dividing are nowhere near the Int range limit, so using an arbitrary-precision bignum type seems like overkill.
What's the right way to do this? Should I just call toInteger on my operands, or is there a better approach (maybe one not involving (%) and ratios) that I don't know about?
You have to convert the operands to floats first and then divide, otherwise you'll perform an integer division (no decimal places).
Laconic solution (requires Data.Function)
foo = (/) `on` fromIntegral
which is short for
foo a b = (fromIntegral a) / (fromIntegral b)
with
foo :: Int -> Int -> Float