2017-06-23 4 views
1

私はコースをオンラインでthe CIS 194 course at the University of Pennsylvaniaを通して自分のやり方で働くことによってハスケルを学ぼうとしています。より「慣用的な」名前Haskellの中へtakewhileとiterateを使用するイディオムのhaskell

fun1 :: [Integer] -> Integer 
fun1 [] = 1 
fun1 (x:xs) 
    | even x = (x - 2) * fun1 xs 
    | otherwise = fun1 xs 

:演習の一つで、学生は再書き込み機能になっています。私はこの機能を

fun1 :: [Integer] -> Integer 
fun1 xs = 
    let spl = partition even xs 
    in foldl (*) 1 ((map (subtract 2) (fst spl)) ++ snd spl) 

と書かれているように書き直しました。それは、文字のほとんどの文字を私がどのようにしてそれをclojureに書き込むかに変換します。代入では、PreludeのtakeWhileiterateを使用して関数を書き換えるヒントを示します。私はその機能が何を表面的に理解していますが、その機能を使用するためにその機能を書き直す方法はすぐにわかりませんでした。 takeWhileiterateを使って、これをどのように書き換えることができますか?

+0

を(少なくとも私の心の中で、) 'takeWhile'と' iterate'で、この関数を記述することは明白な、自然な方法はありません。何かあれば、これは精神的な体操の運動です。また、2番目の関数は最初の関数と同じではないことに注意してください。最初の関数は奇数の値を無視し、2番目の関数は奇数の値を無視します。 – user2407038

+0

@ user2407038ええ、私はエクササイズの本質を誤解していました。したがって私はパーティションと連結を使用していました。 –

答えて

3

これは実際にはtakeWhileとはあまり関係ありません。指定されたリストのの場合はx-2の場合はの製品を計算してください。

fun1 :: [Integer] -> Integer 
fun1 [] = 1 -- the product of an empty list is 1 
fun1 (x:xs) 
    -- if the number is even, we multiply (x-2) with the remaining part 
    | even x = (x - 2) * fun1 xs 
    -- if the number is odd, we ignore x and return the fun1 of the tail 
    | otherwise = fun1 xs 

だから、としてそれを書くことができます:確かにあなたがproductを使用することはできません場合は

fun1 :: Integral i => [i] -> i 
fun1 = product . map (subtract 2) . filter even 

は、使用することができます - 使用 - あなたが疑問に行ったように:

fun1 :: Integral i => [i] -> i 
fun1 = foldl (*) 1 . map (subtract 2) . filter even 

pointfreeバージョン:fun1の頭にはパラメータやラムダ式がありません。だから私たちは価値の面で考えるのではなく、機能の面でもっと考えます。リスト[1,3,4]については

、これが生成します。

Prelude> (foldl (*) 1 . map (subtract 2) . filter even) [1,3,4] 
2 
関連する問題