I'm still new and trying to create a list for use in a function and want to keep it as small as possible which happens to be logBase x y.
but I'm having trouble getting logBase into something I can use in this list.
[1 .. (logBase x y)]
Any suggestions?
You don't post what type error you get, but I imagine it is something like this:
Prelude> let x = 2
Prelude> let y = 7
Prelude> [1 .. (logBase x y)]
<interactive>:1:7:
No instance for (Floating Integer)
arising from a use of `logBase' at <interactive>:1:7-17
Possible fix: add an instance declaration for (Floating Integer)
In the expression: (logBase x y)
In the expression: [1 .. (logBase x y)]
In the definition of `it': it = [1 .. (logBase x y)]
The problem is that:
Prelude> :t logBase
logBase :: (Floating a) => a -> a -> a
returns a type in the Floating class, while other variables in your program (1, 'x', 'y') are of integral type.
I presume you want a sequence of Integers?
Prelude> :set -XNoMonomorphismRestriction
Prelude> let x = 2
Prelude> let y = 42
Prelude> [1 .. truncate (logBase x y)]
[1,2,3,4,5]
Use truncate, celing or floor.
You probably want one of the functions list here. Hoogle and Hayoo! are great tools for this kind of thing since they let you put in the type of the function you want and get back a list of functions. With Haskell's rich type system this can be a very helpful tool, much more so than dynamically typed languages or even statically typed languages like C or Java.
You probably want some sort of rounding, truncate, floor, or ceiling function. Ints and Floats are different types (as you've seen) and the compiler won't let you mix them. I'll find a reference in a minute.
Related
I am teaching myself Haskell, and playing with list comprehensions. I wrote this list comprehension:
[ c | a <- [1..3], b <- [1..4], let c = hyp a b, c == round c]
I hoped it would produce the list of values c where c is an integer (c == round c), which would be only 5, but it does not compile. Playing around some more, I've found I can't really embed any functions in a list comprehension, I'm sure there is a way, I just don't know how.
Here's the error code:
<interactive>:158:1: error:
• Ambiguous type variable ‘t0’ arising from a use of ‘it’
prevents the constraint ‘(Floating t0)’ from being solved.
Probable fix: use a type annotation to specify what ‘t0’ should be.
These potential instances exist:
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
Thanks!
First of all, include necessary definitions in a question like this.
hyp :: Floating a => a -> a -> a
hyp a b = sqrt $ a^2 + b^2
Now. You can “embed” functions all right in list comprehensions. Apparently you just chose some unfortunate ones! round has the following type:
GHCi, version 7.10.2: http://www.haskell.org/ghc/ :? for help
Prelude> :t round
round :: (Integral b, RealFrac a) => a -> b
So, for round c == c to make sense, you'd need to have a number type that's both an instance of Integral and of RealFrac. In other words, this type would contain fractions, yet all its elements would be integers†. Well, you can't have your cake and eat it too!
This problem would have been much more evident, like so often in Haskell, if you had actually written out some type signatures. While fooling around like that, it often helps to just select some simple example type. Perhaps the most reasonable thing would seem:
Prelude> [ c | a <- [1..3], b <- [1..4], let c = hyp a b, c == round c] :: [Integer]
<interactive>:6:41:
No instance for (Floating Integer) arising from a use of ‘hyp’
In the expression: hyp a b
In an equation for ‘c’: c = hyp a b
In the expression:
[c |
a <- [1 .. 3], b <- [1 .. 4], let c = hyp a b, c == round c] ::
[Integer]
Ok, so Integer doesn't work because you're trying to do real arithmetic, with those square roots in hyp. This is not possible with Integer, you need a Floating type like Double. Let's try that:
Prelude> [ c | a <- [1..3], b <- [1..4], let c = hyp a b, c == round c] :: [Double]
<interactive>:8:55:
No instance for (Integral Double) arising from a use of ‘round’
In the second argument of ‘(==)’, namely ‘round c’
In the expression: c == round c
In a stmt of a list comprehension: c == round c
Ok, this is because as I said, round always gives integral-type results. However, you can always convert such an integral type to a Double again:
Prelude> [ c | a <- [1..3], b <- [1..4], let c = hyp a b, c == fromIntegral (round c)] :: [Double]
[5.0]
Note that this is not really a good solution though: you don't really want the result to be floating point if you go already check that the elements are really integral! I'd recommend in this case not just evaluating hyp as such at all. Better use this comprehension:
Prelude> [ c | a <- [1..3], b <- [1..4], let c² = a^2 + b^2; c = round . sqrt $ fromIntegral c², c^2==c²] :: [Integer]
[5]
One big argument for this version is that it does the comparison in Integer, not in Double. Floating-point equality comparison is something you should best stay away from entirely if you can help it; in this case it's mostly harmless because the interesting thing is the integer subset, which can in fact be represented exactly (unlike decimal fractions like 0.1). Still you ca get wrong results this way: in particular, for sufficiently large floating-point numbers, c == fromInteger (round c) will always be true, because above a certain threshold all values are integral after all.
Prelude> [ c | a <- take 4 [1000000000000..], b <- take 5 [1000000000000..], let c = hyp a b, c == fromIntegral (round c)] :: [Float]
[1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12,1.4142135e12]
But none of these are actually correct integral hypothenuses, as you can see with the version that does the comparison in Integer:
Prelude> [ c | a <- take 4 [1000000000000..], b <- take 5 [1000000000000..], let c² = a^2 + b^2; c = round . sqrt $ fromIntegral c², c^2==c²] :: [Integer]
[]
Strictly speaking, this improved version is also not safe though – it doesn't give false positives, but may not find actual Pythagorean triples because the lossy floating-point steps can already destroy equality. To do it real properly, you need an all-integral
intSqrt :: Integral a => a -> Maybe a
This could probably done quite efficiently by taking the float sqrt as a starting value for a few rounds of pseudo Newton-Raphson in integer arithmetic.
†In principle, the round function could also have a more relaxed signature.
round' :: (Num b, RealFrac a) => a -> b
round' = fromInteger . round
With that version, your original code would work.
I'm trying to create a foldr example that converts an Integral to a list of digits (i.e., [Int]).
pickDigit num pos = (num `div` (10^pos)) `mod` 10
toDigits num = foldr (\pos acc -> (pickDigit num pos):acc) [] [0 .. floor (logBase 10 num)]
This loads successfully. But when I try to run it, for example
> toDigits 1234
I get a type error message I don't understand.
When I ask Haskell for the types of the loaded code and explicitly include those types in the source file, I get error messages on loading. When I try to explicitly restrict the types to Integer or Int, I get more error messages.
I'd appreciate some suggestions. Thanks.
logBase requires Floating, but it's not
This works:
[0 .. floor (logBase 10 $ fromIntegral num)]
xs = [1,2,3]::[Float]
ys = map (+) xs
This was a question in an old test and there is no solution sheet.
The questions:
1) What kind of signature does ys have?
2) Explain why and draw how ys looks like
For the first question I know that xs is of type float and so should ys(I run the program in ghci too).
As for the second one I have no idea, because when I run the code nothing happens. When I run it and the run ys on a separate row I get an error.
Can someone help me with a hint?
For the first question I know that xs is of type float
er, no. xs has type [Float]: a list of floats.
and so should ys
ys does not have the same type as xs. You probably think so because you've read that + requires the arguments and result to have the same type:
(+) :: Num a => a -> a -> a
...or if you instantiate it to Float numbers
(+) :: Float -> Float -> Float
This is correct, nevertheless (+) is not an endomorphism (a function mapping a type to itself, as it would have to be if ys was the same type as xs) because it has two number arguments.
With map (+) you're considering (+) as a function of a single argument, not of two arguments. In most programming languages this would actually be an error, but not so in Haskell: in Haskell, all functions actually have only one argument. Functions with “multiple arguments” are really just functions on interesting types, that make it seem as if you're passing multiple arguments. In particular, the signature of (+) is actually shorthand for:
(+) :: Float -> (Float -> Float)
So, considered as a one-argument function, (+) actually maps numbers to number-endomorphisms. Hence,
map (+) :: [Float] -> [Float -> Float]
and
ys :: [Float -> Float]
– a list of number-functions. Specifically, it's this list:
ys = [(+) 1 , (+) 2 , (+) 3 ]
≡ [(1+) , (2+) , (3+) ]
≡ [\n -> 1+n, \n -> 2+n, \n -> 3+n]
I could, for example, use it like this:
GHCi> let [f,g,h] = ys in [f 3, g 2, h 1]
[4,4,4]
GHCi> map ($ 10) ys -- applies all functions separately to the number 10
[11,12,13]
GHCi> foldr ($) 0 ys -- applies all the functions one after another to 0
6
BTW, IMO you're asking the question the wrong way around. In Haskell, you don't want to consider some code and wonder what type it has – that is more an ML or even Lisp approach. I'd always start with the type signature, and work out the implementation “outside to in” (typed holes are very handy for this). This possibility is one of the big advantages of functional programming in comparison to procedural languages.
I don't have ghci at the moment, apologies if something I say is wrong.
xs is type [Float] and ys is of type [Float -> Float](it's a list of functions that each take a Float and return a Float). ys will be [(+) 1, (+) 2, (+) 3] because map applies (+) to each elements in xs. But you cannot print ys because functions do not derive Show
ys type is [Float -> Float], a list of functions that receive a number return the number +1 (first elem), the number + 2 (the second) and the number +3 (the last).
Please, bear in mind that + is a is applied with a single argument for each list element so it does return another function.
If you wanted to add all the items in the List, you should use a reduce function, such as foldl.
let zs = foldl (+) 0 xs
I hope this helps.
Cristóbal
(product (take 9 [1000,999..])) `div` (product (map (\j-> product [1..j]) (map (\j->length(j)) (group [2,2,2,2,2,2,2,2,2]))))
The above code is of the form X div Y, with X=product (take 9 [1000,999..]) & Y=(product (map (\j-> product [1..j]) (map (\j->length(j)) (group [2,2,2,2,2,2,2,2,2]))))
If I copy and paste the code in ghci, it gives me -12740133310672 as an answer,
but if I count X & Y individually, I get 964541486381834014456320000 & 362880, then dividing them gives me 2658017764500203964000 as an answer.
I think this incoherence might be because the number is too large, but since the computer can calculate X and Y correctly individually, how come it can't also divide them combined?
Prelude Data.List> let x = product $ take 9 [1000,999..]
Prelude Data.List> x
964541486381834014456320000
Prelude Data.List> :t x
x :: (Enum a, Num a) => a
Observe that x has the type of a generic number: you calculated it with just operations that work for any number type. When you evaluate such a number in GHCi, it defaults to the “safest” concrete type, which is Integer, an arbitrary-precision type which has no problem with big numbers. However, you can enforce the calculation to be done with any other numerical type:
Prelude Data.List> x :: Integer
964541486381834014456320000
Prelude Data.List> x :: Float
9.645414e26
Prelude Data.List> x :: Double
9.645414863818342e26
Prelude Data.List> x :: Int
-4623139575776374784
The floating point versions are inaccurate but still close, whereas Int (a machine-size fixed precision number) simply overflows and gives complete bogus.
Normally this won't bother you, because huge calculations are by default done with the safe Integer type.
That is, unless something else prevents it.
Prelude Data.List> let y = product (map (\j-> product [1..j]) $ map length (group [2,2,2,2,2,2,2,2,2]))
Prelude Data.List> y
362880
Prelude Data.List> :t y
y :: Int
Unlike x, the type of y is already concrete: it must be Int, because that's the result type of length. (The rationale being: a list that's so big that you couldn't measure its length with an Int would not be able to fit in memory anyway.)
Now, div, like most numeric functions in Haskell, requires that the arguments and result have all the same type. For this reason, x`div`y will as a whole be calculated as Int instead of Integer, including x. And as we've seen, calculating x as Int gives bogus.
OTOH, if you use 362880 as a literal, then this isn't connected to length. It's just a generic number, like x, hence GHCi will again default to safe Integer, i.e. you get
Prelude Data.List> x `div` 362880
2658017764500203964000
The same result can be achieved if you just allow conversion of y:
Prelude Data.List> x `div` fromIntegral y
2658017764500203964000
Using Integer instead of Int helps:
let r :: Integer ; r = (product (take 9 [1000,999..])) `div` (product (map (\j-> product [1..j]) (map (\j->fromIntegral $ length(j)) (group [2,2,2,2,2,2,2,2,2]))))
gets me: 2658017764500203964000
I don't fully understood your code, but I assume if you calculate them individually you get smaller intermediate results - so Int won't overflow.
So yes - the incoherence is because of large numbers (Int is limited in it's width, so it will just overflow (negative numbers). If you operate with such large numbers you should probably use Integer, which has unlimited width.
I am not able to explain the following behavior:
Prelude> let x = 1 + 2
Prelude> let y = (x,x)
Prelude> :sprint y
Prelude> y = _
Now when I specify a type for x:
Prelude> let x = 1 + 2 ::Int
Prelude> let y = (x,x)
Prelude> :sprint y
Prelude> y = (_,_)
Why does the specification of x's type force y to its weak head normal form (WHNF)?
I accidentally discovered this behavior while reading Simon Marlow's Parallel and Concurrent Programming In Haskell.
Here's an informed guess. In your first example,
x :: Num a => a
So
y :: Num a => (a, a)
In GHC core, this y is a function that takes a Num dictionary and gives a pair. If you were to evaluate y, then GHCi would default it for you and apply the Integer dictionary. But from what you've shown, it seems likely that doesn't happen with sprint. Thus you don't yet have a pair; you have a function that produces one.
When you specialize to Int, the dictionary is applied to x, so you get
x :: Int
y :: (Int, Int)
Instead of a function from a dictionary, x is now a thunk. Now no dictionary needs to be applied to evaluate y! y is just the application of the pair constructor to two pointers to the x thunk. Applying a constructor doesn't count as computation, so it's never delayed lazily.