Я хочу реализовать алгоритм, использующий ST
монады и STUArray
с, и я хочу, чтобы иметь возможность работать с обеими Float
и Double
данных.STUArray с полиморфным типом
Я продемонстрирую более простой пример проблемы: вычисление memoized scanl (+) 0
(я знаю, что это можно решить без STUArray
, просто используя в качестве примера).
{-# LANGUAGE FlexibleContexts, ScopedTypeVariables #-}
import Control.Monad
import Control.Monad.ST
import Data.Array.Unboxed
import Data.Array.ST
accumST :: forall a. (IArray UArray a, Num a) => [a] -> Int -> a
accumST vals = (!) . runSTUArray $ do
arr <- newArray (0, length vals) 0 :: ST s (STUArray s Int a)
forM_ (zip vals [1 .. length vals]) $ \(val, i) ->
readArray arr (i - 1)
>>= writeArray arr i . (+ val)
return arr
Это терпит неудачу с:
Could not deduce (MArray (STUArray s) a (ST s)) from the context()
arising from a use of 'newArray'
Possible fix:
add (MArray (STUArray s) a (ST s)) to the context of
an expression type signature
or add an instance declaration for (MArray (STUArray s) a (ST s))
Я не могу применить предложенный "Возможные исправления". Потому что мне нужно добавить что-то вроде (forall s. MArray (STUArray s) a (ST s))
в контекст, но afaik это невозможно ..
Правила только срабатывают, если скомпилированы с включенными оптимизациями. –
В конце концов я использовал другое обходное решение - см. Ответ ниже – yairchu