在 Haskell 中使用带有列表列表的映射时出现问题

发布于 2024-08-05 17:52:53 字数 308 浏览 9 评论 0原文

我正在使用 Haskell 解决 euler 项目中的问题 99,其中我必须从基本指数对列表中找到最大结果。

我想出了这个:

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

数字的形式是:

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

为什么这不起作用?我需要更改数字的格式吗? 这里是否有我没有想到的简单优化,例如更有效的求幂方法?

I am using Haskell to solve problem 99 in euler project, where I must 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 this work? Do I need to change the format of the numbers?
Is there a simple optimisation here I am not thinking of, like a more efficient method of exponentiation?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

傲世九天 2024-08-12 17:52:53

授人以鱼,可食一日;授人以鱼,可食一生。

Jonno,您应该学习如何让 GHC 的错误消息帮助您,以及“undefined drop in”方法(现在让我们关注它)。

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!

Give a man a fish, and you'll feed him for a day, teach a man to fish, and you'll feed him for a lifetime.

Jonno, you should learn how to let GHC's error messages help you, and the "undefined drop in" 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!
握住我的手 2024-08-12 17:52:53

不起作用的是程序的类型一致性。您正在尝试应用函数 (^),简化类型 Int ->整数-> Int,对于类型为 (a,a) -> 的参数a(不是 Int)。

最简单的方法可能是直接生成对列表而不是列表列表。然后,您(几乎)可以直接将 (^) 函数应用于它们,首先取消柯里化。

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

如果您对子列表感到困惑,您可以直接对它们进行模式匹配,从而对 Matajon 的解决方案进行一些改进:

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

或者,如果您一直喜欢无点样式,则可以充分利用 控制.箭头。 (在这种情况下,就冗长而言没有多大帮助)

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

What's not working is your program's type consistency. You're trying to apply function (^), simplified type Int -> Int -> Int, to arguments of type (a,a) -> a (not an Int).

The easiest way would probably be to directly generate a list of pairs instead of a list of lists. You can then (almost) directly appply the (^) function to them, uncurrying it first.

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

If you're stuck with your sublists, you could pattern-match them directly, improving a bit on Matajon's solution:

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

Or, if you're into point-free style all the way, you can make good use of the operators in Control.Arrow. (which in this case doesn't help much as far as verbosity goes)

prob99 = maximum $ map ((!!0) &&& (!!1) >>> uncurry (^)) numbers
拍不死你 2024-08-12 17:52:53

因为 fst 和 snd 是在对上定义的(类型 fst :: (a,b) -> a 和 snd :: (a,b) -> b)。第二个问题是 (fst)^(snd),你不能对函数进行幂函数。

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

或者

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

Because fst and snd are defined on pairs (types fst :: (a,b) -> a and snd :: (a,b) -> b). And second problem is with (fst)^(snd), you cannot power function on function.

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

or

prob99 = maximum $ map (\xs -> (xs !! 0)^(xs !! 1)) numbers
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文