計算機科学のブログ

実践Haskell 効率的でステートフルな配列 STUArrayを使って状態を変化させる、writeArray関数、クロスオーバー(交叉)、限界値条件、先頭と末尾

入門Haskellプログラミング (Will Kurt(著)、株式会社クイープ(監修、翻訳)、翔泳社)のUNIT7(実践Haskell)、LESSON 42(Haskellでの効率的でステートフルな配列)、42.6(練習問題)Q42-1の解答を求めてみる。

コード

import Control.Monad
import Control.Monad.ST
import Data.Array.ST
import Data.Array.Unboxed

crossOver :: (UArray Int Int, UArray Int Int) -> Int -> UArray Int Int
crossOver (array1, array2) index = runSTUArray $ do
  stArray <- thaw array1
  let end = (snd . bounds) array1
  forM_ [index .. end] $ \i -> do
    writeArray stArray i (array2 ! i)
  return stArray

a1 :: UArray Int Int
a1 = array (0, 4) $ zip [0 .. 4] $ repeat 1

a2 :: UArray Int Int
a2 = array (0, 4) []

a3 :: UArray Int Int
a3 = crossOver (a1, a2) 3

main :: IO ()
main = do
  mapM_ print [a1, a2, a3]

入出力結果(Terminal, Zsh)

% runghc sample1.hs
array (0,4) [(0,1),(1,1),(2,1),(3,1),(4,1)]
array (0,4) [(0,0),(1,0),(2,0),(3,0),(4,0)]
array (0,4) [(0,1),(1,1),(2,1),(3,0),(4,0)]
%