2

私はハスケルを使用してオイラープロジェクトの問題99を解決しています。ここでは、基本指数ペアのリストから最大の結果を見つける必要があります。

私はこれを思いついた:

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

番号の形式は次のとおりです。

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

なぜこれが機能しないのですか?数字の形式を変更する必要がありますか?より効率的なべき乗の方法のように、私が考えていない単純な最適化がここにありますか?

4

3 に答える 3

12

男に魚を与えれば、あなたは彼に一日餌を与え、男に魚を教え、そしてあなたは彼に一生餌を与えます。

Jonno、GHCのエラーメッセージを役立てる方法と「undefinedドロップイン」方法を学ぶ必要があります(今はそれに焦点を当てましょう)。

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!
于 2009-09-30T10:11:44.180 に答える
5

動作していないのは、プログラムの型の一貫性です。(^)関数、簡略化された型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。(この場合、冗長性に関してはあまり役に立ちません)

prob99 = maximum $ map ((!!0) &&& (!!1) >>> uncurry (^)) numbers
于 2009-09-30T08:09:16.707 に答える
4

fstとsndはペアで定義されているため(タイプfst ::(a、b)->aおよびsnd::(a、b)-> b)。そして2番目の問題は(fst)^(snd)であり、関数の電源をオンにすることはできません。

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

また

prob99 = maximum $ map (\xs -> (xs !! 0)^(xs !! 1)) numbers
于 2009-09-30T07:52:25.117 に答える