2

次のように、入力に応じてリストの値を変更するための非常に単純な関数をhaskellで記述しようとしています

update_game :: [Int] -> Int -> Int -> [Int]
update_game (x:xs) row take_amnt | row == 1 = x - take_amnt:xs
                                 | row == 2 = x : head(xs) - take_amnt : tail(xs)
                                 | row == 3 = x : head(xs) : last(xs) - take_amnt`

最初の 2 つのケースは問題なく動作しますが、最後のケースでは問題が発生し、その理由がわかりません。エラーは次のとおりです。

http://i.stack.imgur.com/jpT8b.png

http://i.stack.imgur.com/tlz5t.png

4

3 に答える 3

2

「:」の2番目のパラメーターはリストである必要がありlast(xs) - take_amnt、要素のみを指定します。

「[]」でラップします。[last(xs) - take_amnt]

于 2012-12-17T20:36:47.900 に答える
2

の 2 番目の引数:はリストである必要がありますが、last(xs) - take_amnt明らかに 1 つの要素しか得られません。試す

row == 3 = x : head(xs) : [last(xs) - take_amnt]
于 2012-12-17T20:34:04.467 に答える
2
last(xs) - take_amnt

は ですIntが、 の 2 番目の引数は(:)リストでなければなりません(:) :: a -> [a] -> [a]

リストが常に 3 つの要素の長さである場合 (ただし、おそらくリストの代わりにタプルを使用する必要があります)、それを a でラップする[ ]と、正しいセマンティクスで解決されます。

update_game :: [Int] -> Int -> Int -> [Int]
update_game (x:xs) row take_amnt | row == 1 = x - take_amnt:xs
                                 | row == 2 = x : head(xs) - take_amnt : tail(xs)
                                 | row == 3 = x : head(xs) : [last(xs) - take_amnt]

ただし、それに応じてパターン マッチングを行う方がよいでしょう。

update_game [x,y,z] 1 take_amnt = [x - take_amnt, y, z]
update_game [x,y,z] 2 take_amnt = [x, y - take_amnt, z]
update_game [x,y,z] 3 take_amnt = [x, y, z - take_amnt]
update_game _       _ _         = error "Invalid input"

またはパターンマッチングなしでジェネリックにする

update_game xs index take_amnt = zipWith (-) xs (replicate (index-1) 0 ++ take_amnt : repeat 0)
于 2012-12-17T20:34:13.780 に答える