    module Data.Array.Repa.Eval.Target
            ( Target    (..)
            , fromList)
    where
    import Data.Array.Repa.Base
    import Data.Array.Repa.Shape
    import Control.Monad
    import System.IO.Unsafe

    -- Target ---------------------------------------------------------------------
    -- | Class of manifest array representations that can be constructed in parallel.
    class Target r e where

     -- | Mutable version of the representation.
     data MVec r e

     -- | Allocate a new mutable array of the given size.
     newMVec          :: Int -> IO (MVec r e)

     -- | Write an element into the mutable array.
     unsafeWriteMVec  :: MVec r e -> Int -> e -> IO ()

     -- | Freeze the mutable array into an immutable Repa array.
     unsafeFreezeMVec :: sh  -> MVec r e -> IO (Array r sh e)

     -- | Ensure the strucure of a mutable array is fully evaluated.
     deepSeqMVec      :: MVec r e -> a -> a

     -- | Ensure the array is still live at this point.
     --   Needed when the mutable array is a ForeignPtr with a finalizer.
     touchMVec        :: MVec r e -> IO ()

    -- | O(n). Construct a manifest array from a list.
    fromList :: (Shape sh, Target r e)
             => sh -> [e] -> Array r sh e
    fromList :: sh -> [e] -> Array r sh e
    fromList sh :: sh
    sh xx :: [e]
    xx
     = IO (Array r sh e) -> Array r sh e
    forall a. IO a -> a
    unsafePerformIO
     (IO (Array r sh e) -> Array r sh e)
    -> IO (Array r sh e) -> Array r sh e
    forall a b. (a -> b) -> a -> b
    $ do   let len :: Int
    len = [e] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [e]
    xx
            if Int
    len Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    /= sh -> Int
    forall sh. Shape sh => sh -> Int
    size sh
    sh
             then [Char] -> IO (Array r sh e)
    forall a. HasCallStack => [Char] -> a
    error "Data.Array.Repa.Eval.Fill.fromList: provide array shape does not match list length"
             else do
                    MVec r e
    mvec    <- Int -> IO (MVec r e)
    forall r e. Target r e => Int -> IO (MVec r e)
    newMVec Int
    len
                    (Int -> e -> IO ()) -> [Int] -> [e] -> IO ()
    forall (m :: * -> *) a b c.
    Applicative m =>
    (a -> b -> m c) -> [a] -> [b] -> m ()
    zipWithM_ (MVec r e -> Int -> e -> IO ()
    forall r e. Target r e => MVec r e -> Int -> e -> IO ()
    unsafeWriteMVec MVec r e
    mvec) [0..] [e]
    xx
                    sh -> MVec r e -> IO (Array r sh e)
    forall r e sh. Target r e => sh -> MVec r e -> IO (Array r sh e)
    unsafeFreezeMVec sh
    sh MVec r e
    mvec