回答編集履歴
1
if -> when の書き換えと、コード例追加
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
|
-
|
20
|
+
when (n > 3) $ calc (n - 2) (i + 2 : result) 0
|
20
|
-
|
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
|
+
```
|