2011-01-23 10 views
0

だから私は、次の機能があります。このエラーとともにのいずれかを使用して正しく

chk2 :: [(Integer,Integer)] -> Either [(Integer,Integer)] (Integer,Integer) 
chk2 [email protected]((n,_):_) 
    | chkp (prod $ lgst i)==True = Right $ lgst i 
    | lgst i==i!!0 = Left $ chk2 $ (4-2,4-2):next i           
    | otherwise = Left $ chk2 $ next i 
    where prod (a,b) = a*b 
     lgst = foldl1 (\(a,b) (c,d) -> if prod (a,b) > prod (c,d) then (a,b) else (c,d)) 
     next t = map (\(a,b) -> if (a,b)==lgst t then (a-1,b+1) else (a,b)) t 

:私は(で終わるのいずれかに、この機能を取得しようとしている

runhugs: Error occurred 
ERROR "4/4.hs":14 - Type error in explicitly typed binding 
*** Term   : chk2 
*** Type   : [(Integer,Integer)] -> Either (Either [(Integer,Integer (Integer,Integer)) (Integer,Integer) 
*** Does not match : [(Integer,Integer)] -> Either [(Integer,Integer)] (Integer,Integer) 

を、 b)すなわち第1のガードまたは[(a、b)]、すなわち後者の2つのガード。後者の2つのガードには基本的な問題があります。再帰を取り除くとすべてうまくいきますが、関数自体を返すときに型シグネチャを定義する方法がわかりません。

+3

ペーストビンが悪い質問をします。将来に役立つために質問は自己完結型でなければなりません。 – Flexo

+0

ちょうどawoodlandと同じように言っていた。今回はコードを貼り付けました。 – houbysoft

+0

@Chris Bolton:ここで何を解決しようとしていますか? –

答えて

3

問題は再発するかどうかです。

chk2のタイプによれば、chk2 $ next iは、タイプEither [(Integer,Integer)] (Integer,Integer)である。 Leftは、タイプb -> Either b aであるため、Left $ chk2 $ next iは、指定されていないタイプのEither (Either [(Integer,Integer)] (Integer,Integer)) aです。aです。

Left $ chk2 $ (4-2,4-2):next iも同様の問題があります。

修正するには、再帰的値をどのように処理するかを決定する必要があります。

簡単修正:

| lgst i==i!!0 = chk2 $ (4-2,4-2):next i           
    | otherwise = chk2 $ next i 

それはすべてあなたの結果はRightなることを意味しかし、私は、これはあなたが望むものである疑い。 私はあなたが何をしたいか分からないので、あなたがしたいことをする方法がわかりません。

リストの結果は何を意味しますか?リスト以外の結果はどういう意味ですか?

あなたがやりたがっているのは、再帰の結果とパターンマッチし、Right pair -> Left [pair]を変換し、おそらく他の結果を前面に追加することです。

例として、同様の型シグネチャを持つ再帰関数を作成します。 fooは整数のリストを取る関数とすると、:

  • リストの最初の要素がリスト全体の最大値であれば、そうでない場合は、その要素
  • を返し、リストのサブシーケンスを返し、各々は、これを行うこととサブシーケンスの次の要素(または端部)との間のすべての要素

の最大値である:

foo :: [Integer] -> Either [Integer] Integer 
foo [] = Left [] 
foo (x:xs) = case foo xs of 
    Left ys -> if all (<=x) ys 
       then Right x 
       else let (_,ys') = break (>x) ys in Left (x:ys') 
    Right y -> if x >= y 
       then Right x 
       else Left [x,y] 

なしどのように私はcaseを使用して、fooへの再帰呼び出しの結果に対してパターンマッチングを行います。

+0

私はどのように修正? :/ –

+0

私はchk2 :: [(Integer、Integer)] - >どちらかを試しました([Integer、Integer)](Integer、Integer))(Integer、Integer)です。 –

+0

一部の修正が含まれるように編集されました。 – rampion

1

オイラー#4を解決するには、あなたはハスケルにとって非常に厄介なスタイルのようです。ハスケルのパラダイムは非常に異なっているので、他の言語のコードをHaskellに "移植"しようとするのは、通常は悪い考えです。

リスト内包表記at the Haskell Wikiを使用するオイラー#4に対する非常にクリーンで賢明な解を見つけることができます。確かに唯一の解決策ではありませんが、現在のコードと少なくとも20倍の可読性があります。犯行はありません。

私は、ハスケルの問題にどのようにアプローチするかを学ぶために、Learn You a HaskellReal World Haskellを強くお勧めします。私の経験では、通常、小型で簡単なヘルパーメソッドを作成して解に構成することです。

+0

私はあなたのことを読んでいますhaskell:P –

関連する問題