在Haskell中将映射与列表一起使用时出现问题

在Haskell中将映射与列表一起使用时出现问题,haskell,dictionary,exponentiation,Haskell,Dictionary,Exponentiation,我正在使用Haskell来解决euler项目中的问题99,其中我必须从基指数对列表中找到最大结果 我想到了这个: prob99 = maximum $ map ((fst)^(snd)) numbers 如果数字的格式为: numbers = [[519432,525806],[632382,518061],[78864,613712].. 为什么这样不行?我需要更改数字的格式吗? 这里有一个我没有想到的简单优化,比如更有效的求幂方法吗?因为fst和snd是成对定义的(类型fst:(a,b)

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

我想到了这个:

prob99 = maximum $ map ((fst)^(snd)) numbers
如果数字的格式为:

numbers = [[519432,525806],[632382,518061],[78864,613712]..
为什么这样不行?我需要更改数字的格式吗?
这里有一个我没有想到的简单优化,比如更有效的求幂方法吗?

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

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


不起作用的是程序的类型一致性。您试图将函数
(^)
,简化类型
Int->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
或者,如果您一直使用无点样式,则可以充分利用
Control.Arrow
中的运算符。(在这种情况下,就冗长而言,这没有多大帮助)

给一个人一条鱼,你会喂他一天;教一个人钓鱼,你会喂他一辈子

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

ghci>let number=[[519432525806],[632382518061]]
ghci>——到目前为止还不错。。
ghci>let prob99=最大$map((fst)^(snd))个数
ghci>--好吧,出了什么问题?
ghci>--我很确定这部分很好:
ghci>let prob99=最大$map未定义的数字
ghci>——是的,很好
ghci>——因此罪犯必须在“((fst)^(snd))”部分
ghci>let f=((fst)^(snd))
ghci>--哇,所以这个函数从来就没有意义,不仅仅是在我使用它的地方。。
ghci>--它正在做我认为它正在做的事情吗?让我们扔掉那些牙套
ghci>设f=fst^snd
ghci>--是的,我的语法正确,好的
ghci>--好的,我可以用fst吗?
ghci>设f=fst^未定义
没有(Num((a,b)->a)的实例
因在1:8-22使用“^”而产生
可能的修复方法:为(Num((a,b)->a))添加实例声明
在表达式中:fst^未定义
在“f”的定义中:f=fst^未定义
ghci>--嗯,fst不是Num
ghci>——这就是我想要的:
ghci>设f x=fst x^snd x
ghci>--现在让我们试试
ghci>let prob99=最大$map f编号
ghci>--仍然不起作用
ghci>——但至少f现在有了一些意义
ghci>:t f
f::(数值a,积分b)=>(a,b)->a
ghci>--让我们为它找到一个示例输入
ghci>头数
[519432,525806]
ghci>:t头编号
总人数::[整数]
ghci>--哦,这是两个整数的列表,而不是元组!
设f[a,b]=a^b
ghci>let prob99=最大$map f编号
ghci>--没有错误?
ghci>——我终于找到了正确的类型!

我如何才能找到主列表中出现最大数字的位置?这是一个完全不同的问题!一个明显的方法是首先找到最大值,然后查找其索引,但这浪费了懒散地生成列表的大部分好处。有更好的方法,但它们需要更多关于您尝试执行的操作的上下文(以及比注释更多的空间)。“uncurry”在前奏中,不需要从“Data.Function”导入它。您还可以对第一个和第二个元素进行模式匹配,即最大$map((a:b:))->a^b)numbers@Jonno_FTW:关于hoogle的讨论,我建议也看看hlint
prob99 = maximum $ map (\[x,y] -> x^y) numbers
prob99 = maximum $ map ((!!0) &&& (!!1) >>> uncurry (^)) numbers
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!