回答編集履歴

1

if -> when の書き換えと、コード例追加

2023/08/29 12:59

投稿

actorbug
actorbug

スコア2242

test CHANGED
@@ -7,6 +7,7 @@
7
7
  Writerモナドを使ってJavaのソースを再現すると、以下のようになると思います。
8
8
  ただし、`i`の意味を変えていて、元のソースで言うと`result[i]`を受け渡す形にしています。
9
9
  あと、出力されるリストの中身が前後反転しています。
10
+ (最初`if`で書いていましたが、`when`の存在を思い出したので書き換えました)
10
11
  ```haskell
11
12
  import Control.Monad.Writer
12
13
 
@@ -16,6 +17,17 @@
16
17
  calc :: Int -> [Int] -> Int -> Writer [[Int]] ()
17
18
  calc 2 result i = tell [i + 2 : result]
18
19
  calc n result i = do
19
- if n > 3 then calc (n - 2) (i + 2: result) 0 else return ()
20
+ when (n > 3) $ calc (n - 2) (i + 2 : result) 0
20
- if n > 2 then calc (n - 1) result (i + 1) else return ()
21
+ when (n > 2) $ calc (n - 1) result (i + 1)
21
22
  ```
23
+ 奇抜なアイディアをご所望とのことですが、あとは差分リストを使うぐらいしか思いつきません。
24
+ コードの見た目はWriterモナドとあまり変わりません。
25
+ ```haskell
26
+ decompose :: Int -> [[Int]]
27
+ decompose n = calc n [] 0 []
28
+
29
+ calc :: Int -> [Int] -> Int -> [[Int]] -> [[Int]]
30
+ calc 2 result i = ((i + 2 : result):)
31
+ calc n result i = (if n > 3 then calc (n - 2) (i + 2 : result) 0 else id) .
32
+ (if n > 2 then calc (n - 1) result (i + 1) else id)
33
+ ```