Problem using map with list of lists in Haskell

I am using Haskell to solve problem 99 in an euler project where I have to find the maximum result from a list of base exponent pairs.

I came up with this:

prob99 = maximum $ map ((fst)^(snd)) numbers

      

Where the numbers are in the form:

numbers = [[519432,525806],[632382,518061],[78864,613712]..

      

Why doesn't it work? Do I need to change the format of numbers? Is there a simple optimization I don't think of as a more efficient exponentiation method?

+2


source to share


3 answers


Since fst and snd are defined for pairs (types fst :: (a, b) β†’ a and snd :: (a, b) β†’ b). And the second problem is with (fst) ^ (snd), you cannot use a function function.

prob99 = maximum $ map (\xs -> (head xs)^(head (tail xs))) numbers

      



or

prob99 = maximum $ map (\xs -> (xs !! 0)^(xs !! 1)) numbers

      

+4


source


Give a man a fish and you feed him for a day, teach a man to fish and you will feed him for life.

Jonno, you should learn how to resolve GHC error messages for you, and the undefined

drop method (let's focus on that for now).



ghci> let numbers = [[519432,525806],[632382,518061]]
ghci> -- so far so good..
ghci> let prob99 = maximum $ map ((fst)^(snd)) numbers

<Bam! Some type error>

ghci> -- ok, what could have gone wrong?
ghci> -- I am pretty sure that this part is fine:
ghci> let prob99 = maximum $ map undefined numbers
ghci> -- yes, it is fine
ghci> -- so the culprit must be in the "((fst)^(snd))" part
ghci> let f = ((fst)^(snd))

<Bam! Some type error>

ghci> -- whoa, so this function never makes sense, not just where I used it..
ghci> -- is it doing what I think it is doing? lets get rid of those braces
ghci> let f = fst ^ snd

<Bam! Same type error>

ghci> -- yeah I got my syntax right alright
ghci> -- well, can I exponent fst?
ghci> let f = fst ^ undefined

No instance for (Num ((a, b) -> a))
  arising from a use of '^' at <interactive>:1:8-22
Possible fix: add an instance declaration for (Num ((a, b) -> a))
In the expression: fst ^ undefined
In the definition of 'f': f = fst ^ undefined

ghci> -- duh, fst is not a Num
ghci> -- this is what I wanted:
ghci> let f x = fst x ^ snd x
ghci> -- now lets try it
ghci> let prob99 = maximum $ map f numbers

<Bam! Some type error>

ghci> -- still does not work
ghci> -- but at least f makes some sense now
ghci> :t f

f :: (Num a, Integral b) => (a, b) -> a

ghci> -- lets find an example input for it
ghci> head numbers

[519432,525806]

ghci> :t head numbers

head numbers :: [Integer]

ghci> -- oh, so it is a list of two integers and not a tuple!
ghci> let f [a, b] = a ^ b
ghci> let prob99 = maximum $ map f numbers
ghci> -- no error?
ghci> -- finally I got the types right!

      

+12


source


What doesn't work is your sequence of program types. You are trying to apply a function (^)

, a simplified type Int -> Int -> Int

, to type arguments (a,a) -> a

(not Int).

The easiest way is probably to directly create a list of pairs instead of a list of lists. Then you can (almost) directly attach the function (^) to them by first discarding it.

numbers = [(519432,525806),(632382,518061),(78864,613712)...
prob99 = maximum $ map (uncurry (^)) numbers

      

If you get stuck with your sublists, you can map them directly to templates by improving Matajon's solution a bit:

prob99 = maximum $ map (\[x,y] -> x^y) numbers

      

Or, if you are fully using the no-reference style, you can effectively use operators in Control.Arrow

. (which doesn't help much in this case, as far as verbosity is concerned)

prob99 = maximum $ map ((!!0) &&& (!!1) >>> uncurry (^)) numbers

      

+5


source







All Articles