私はこの 1、2 か月間 Haskell を学んでおり、最近このコーディングの問題を解決しました。追加の課題は、余分なスペースなしで線形時間でタスクを実行することでしたが、純粋に関数的な方法で実行できるとは思わなかったので、自然に ST モナドについて知り、これは良い機会になると思いました。それについてもっと学ぶために。とにかく、ここに私が書いたコードがあります:
module FindDuplicates where
import Control.Monad (foldM)
import Control.Monad.ST
import Data.Array.ST
xs = [4,3,2,7,8,2,3,1] :: [Int]
findDuplicates :: [Int] -> ST s [Int]
findDuplicates xs = do
arr <- newListArray (1, length xs) xs :: ST s (STArray s Int Int)
let go :: [Int] -> Int -> ST s [Int]
go acc i = do x <- abs <$> readArray arr i
y <- readArray arr x
if y < 0
then return (x:acc)
else do writeArray arr x (-y)
return acc
foldM go [] [1..length xs]
アイデアは、1 ≤ a[i] ≤ n であり、各要素が最大 2 回出現するという前提条件を使用することです。しかし、コードは私に次のエラーを与えます。
FindDuplicates.hs:14:36:
No instance for (MArray (STArray s) Int (ST s1))
arising from a use of ‘readArray’
In the second argument of ‘(<$>)’, namely ‘readArray arr i’
In a stmt of a 'do' block: x <- abs <$> readArray arr i
In the expression:
do { x <- abs <$> readArray arr i;
y <- readArray arr x;
if y < 0 then
return (x : acc)
else
do { writeArray arr x (- y);
.... } }
誰かが私を正しい方向に向けてくれることを願っています!