2017-11-03 24 views
0

私はプログラムで作業していますが、トリはトリプルのリストを取ります。それらのうちのどれかに応じて、他の部分の合計トリプルリストの一部を累積するプログラムを作成する - Haskell

totalWeightOfFirstClass :: [Parcel] -> Weight 
totalWeightOfFirstClass [] = go 
totalWeightOfFirstClass ((weight, postcode, firstclass):xs) = 
    if firstclass == True then 
    go weight 
    totalWeightOfFirstClass xs 
    else 
    totalWeightOfFirstClass xs 
where 
    go :: Int -> Int 
    go _ = 0 
    go x = 

だから、プログラムは、リスト内のすべての重み値を追加し、そのトリプルはファーストクラスだった場合にのみ、最後にそれを表示する必要があります。これまでは、すべての値を累積して最後に表示するというヘルパーステートメントがあります。

何か助けやアドバイスをいただければ幸いです。

よろしく、Kieran。

答えて

1

私が正しくあなたを理解していた場合は、小包が最初にクラスを送信する重みの和をしたい、これはトリックを行う必要がありますが:

totalWeightOfFirstClass :: [Parcel] -> Weight 
totalWeightOfFirstClass [] = 0 
totalWeightOfFirstClass ((weight, postcode, firstclass):xs) 
    | firstclass = weight + totalWeightOfFirstClass xs 
    | otherwise = totalWeightOfFirstClass xs 
+0

これはむしろ非効率的になるでしょう。なぜ見えますか? – dfeuer

+0

@dfeuer最初にフィルタリングして余分なメモリを取り除き、より速くすることができますが、tailは再帰的で、sum関数の標準的な再帰的実装と思われます。私は個人的にHuStmpHrrrのソリューションと同様の方法で実装しますが、理解しやすいようにしたいと思っていました。 – Zpalmtree

+0

@dfeuerなぜ私は見ることができません。おそらくあなたは自分自身を言うことができますか? –

2

あなたのコード内であまりにも多くの仕事です。このような基本的な再帰を書くのではなく、コードを表現するために汎用コンビネータを使用することを検討してください。

totalWeightOfFirstClass = sum . (fmap (\(weight, _, _) -> weight)) . filter (\(_, _, firstc) -> firstc) 

フィルターを適用した後、すべての重みを合計します。ご覧のように、このコードは非常にきれいで読みやすくなっています。

+1

これを読みやすくするために、 'let'または' where'を使って長鎖を分割することができます。少なくとも、改行やコメントを追加してください! – dfeuer

+0

ちょうどいくつかのヘルパー関数が大きな可読性の違いを作り出しています。 'weight(w、_、_)= w;を定義した後、 firstclass(_、_、fc)= fc'の場合、これは 'sumになります。マップの重み。フィルターfirstclass'。 –

+0

@DanielWagnerは間違いなくもしそれが 'data'型でレコード構文で定義されていれば、それらの関数は自由です。 – HuStmpHrrr

関連する問題