2017-12-26 21 views
0

再帰を使って2つのリストの合計を見つける関数を書くのが難しいです。リストが空の場合はNothingになる可能性があります。たぶん再帰

以下の機能の数学は、次のとおり

WおよびXはここ

等しい長さのint配列で

Σw[i]x[i] 

は自分の作業コードである:ここ

example :: [Int] -> [Int] -> Int 
example [] [] = 0 
example (x:xs) (l:ls) = ((x*l) + (example xs ls)) 

での考えであります私が働きたいこと:

example :: [Int] -> [Int] -> Maybe Int 
example [] [] = Nothing 
example (x:xs) (l:ls) = Just((x*l) + (example xs ls)) 

おかげ

答えて

4

2つの入力リストの長さに違いがある場合、Nothingを生成する機能を使用したいと思っていますか?あなたの意図はここにあります。

「ハッピー」の基本ケースは、最初の試行と同じように0ですが、Maybeに持ち上げられました。

example [] [] = Just 0 

リストの長さが異なる状況に対処するには、リストの唯一が空である場合があります。これらのケースを含まないために非網羅的なパターンマッチについてコンパイラ警告を受けているはずです。

example [] _ = Nothing 
example _ [] = Nothing 

最後に、空でない2つのリストがあります。それはMaybeFunctorであるという事実を利用して、むしろexample xs ysに直接追加を適用するより除いて、あなたの最初の試み、我々fmapexample xs ys以上の付加から、その行によく似ています。

example (x : xs) (y : ys) = fmap (x * y +) (example xs ys) 

使用例:ところで

λ> example [1,2] [3,4] 
Just 11 

λ> example [1,2] [3,4,5] 
Nothing 

あなたはこのライブラリを使用したい場合は、safeはワンライナーにこれを有効にするための良い選択です。

import Safe.Exact 

example xs ys = fmap sum (zipWithExactMay (*) xs ys) 
+0

なぜ最初の例ではちょうど11と10だけではないのですか? – Soldalma

+1

@ Soldalma(1 * 3)+(2 * 4)を計算しているためです。 – Potato44

+0

よろしくお願いします。私はまだHaskellの構文に慣れていない場合があります。 – Soldalma

1

あなたは近いですが、example xs lsにあなたの再帰呼び出しはMaybe Intを返し、最後の行に、したがって、あなたのエラー、(x*l + example xs ls中)IntMaybe Intを追加することはできません。

example :: [Int] -> [Int] -> Maybe Int 
example [] []   = Nothing 
example (x:xs) (l:ls) = Just $ x * l + fromMaybe 0 (example xs ls) 

代わりに(そしてもっときれい)、あなたはこのようなものを使用して明示的な再帰を避けることができます:デフォルトの和として0を使用して、このような場合に対処するためにfromMaybeを使用することができます

example [] [] = Nothing 
example xl yl = Just $ sum $ zipWith (*) xl yl 

パターンマッチには網羅的ではないパターンがあります。長さの異なる2つのリストは、パターンマッチ例外を引き起こします。

+0

再帰的解法は、最終的には空リストケースに到達するため、常に「Nothing」を返します。 – mschmidt

+0

@mschmidt修正しました。ありがとうございます。 – hnefatl