2017-02-19 12 views
0

リストを取り、各要素の値がavgより高いかどうかをチェックして、その場合はval - avgを出力します。私はすでに再帰でそれを実装しました、私はmap関数を使用するためにそれを変換したいと思います。再帰の代わりにマップを使用

loop [] = return() 
loop (x:xs) 
     | x > average = print (x - average) >> loop xs 
     | otherwise = loop xs 

任意の提案?

+0

生きるための良いルールは、できるだけ純粋なコードを除外することです。その精神の中で私は 'mapM_print 'と書くでしょう。 foo where foo = map(平均を引く)。フィルタ(>平均) 'あなたが書いたもののタイプだけでなく、あなたがすでに書いたもののタイプを書くのに本当に役立ちます:あなたは 'map'を使いたいと言うので、あなたが意図している関数のタイプは何ですか? 'map'に渡しますか?あなたがこれまで考えていたようには見えない – jberryman

答えて

7

loopの各ステップは、リストの各要素から印刷アクションを生成し、残りの要素と組み合わせる((>>)を使用)という2つのことをすぐに行います。 loopmapとして記述したい場合は、これら2つのサブステップを解消する必要があります。たとえば、あなたは...

printDiffIfAboveAvg :: Double -> IO() 

を関数を定義することができます...そしてmap printDiffIfAboveAvgと、リストのすべての要素に適用します。それはあなたが、単一の全体的な行動に結合する必要がありますタイプ[IO()]のアクションのリストが表示されます:

runAllActions :: [IO()] -> IO() 

runAllActionsはすでにsequence_と呼ばれる、より一般的なバージョンでは、ベースライブラリに存在します。

sequence_ :: (Foldable t, Monad m) => t (m a) -> m() 

だからloop = sequence_ . map printDiffIfAboveAvgになります。実際には、sequence_mapのまさにこの組み合わせを行う基地ライブラリ内の別の関数...

mapM_ :: (Foldable t, Monad m) => (a -> m b) -> t a -> m() 

は...もあります。

関連する問題