{-# LANGUAGE TupleSections #-}

{- |
Module      : Language.Egison.Data.Collection
Licence     : MIT

This module provides some helper functions that operates on / returns
collections.
-}

module Language.Egison.Data.Collection
  ( expandCollection
  , isEmptyCollection
  , unconsCollection
  , unsnocCollection
  , collectionToRefs
  , collectionToList
  , makeICollection
  ) where

import           Control.Monad.Except       (lift, liftIO)
import           Control.Monad.Trans.Maybe  (runMaybeT)

import           Data.Foldable              (toList)
import           Data.IORef
import           Data.Maybe                 (fromJust)
import           Data.Sequence              (Seq, ViewL (..), ViewR (..), (><))
import qualified Data.Sequence              as Sq

import           Language.Egison.Data
import           Language.Egison.Data.Utils
import           Language.Egison.MList
import           Language.Egison.Match

expandCollection :: WHNFData -> EvalM (Seq Inner)
expandCollection :: WHNFData -> EvalM (Seq Inner)
expandCollection (Value (Collection Seq EgisonValue
vals)) =
  (EgisonValue
 -> StateT EvalState (ExceptT EgisonError RuntimeM) Inner)
-> Seq EgisonValue -> EvalM (Seq Inner)
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM ((ObjectRef -> Inner)
-> StateT EvalState (ExceptT EgisonError RuntimeM) ObjectRef
-> StateT EvalState (ExceptT EgisonError RuntimeM) Inner
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ObjectRef -> Inner
IElement (StateT EvalState (ExceptT EgisonError RuntimeM) ObjectRef
 -> StateT EvalState (ExceptT EgisonError RuntimeM) Inner)
-> (EgisonValue
    -> StateT EvalState (ExceptT EgisonError RuntimeM) ObjectRef)
-> EgisonValue
-> StateT EvalState (ExceptT EgisonError RuntimeM) Inner
forall b c a. (b -> c) -> (a -> b) -> a -> c
. WHNFData
-> StateT EvalState (ExceptT EgisonError RuntimeM) ObjectRef
newEvaluatedObjectRef (WHNFData
 -> StateT EvalState (ExceptT EgisonError RuntimeM) ObjectRef)
-> (EgisonValue -> WHNFData)
-> EgisonValue
-> StateT EvalState (ExceptT EgisonError RuntimeM) ObjectRef
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EgisonValue -> WHNFData
Value) Seq EgisonValue
vals
expandCollection (ICollection IORef (Seq Inner)
innersRef) = IO (Seq Inner) -> EvalM (Seq Inner)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Seq Inner) -> EvalM (Seq Inner))
-> IO (Seq Inner) -> EvalM (Seq Inner)
forall a b. (a -> b) -> a -> b
$ IORef (Seq Inner) -> IO (Seq Inner)
forall a. IORef a -> IO a
readIORef IORef (Seq Inner)
innersRef
expandCollection WHNFData
val = (CallStack -> EgisonError) -> EvalM (Seq Inner)
forall a. (CallStack -> EgisonError) -> EvalM a
throwErrorWithTrace (String -> WHNFData -> CallStack -> EgisonError
TypeMismatch String
"collection" WHNFData
val)

isEmptyCollection :: WHNFData -> EvalM Bool
isEmptyCollection :: WHNFData -> EvalM Bool
isEmptyCollection (Value (Collection Seq EgisonValue
col)) = Bool -> EvalM Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> EvalM Bool) -> Bool -> EvalM Bool
forall a b. (a -> b) -> a -> b
$ Seq EgisonValue -> Bool
forall a. Seq a -> Bool
Sq.null Seq EgisonValue
col
isEmptyCollection coll :: WHNFData
coll@(ICollection IORef (Seq Inner)
innersRef) = do
  Seq Inner
inners <- IO (Seq Inner) -> EvalM (Seq Inner)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Seq Inner) -> EvalM (Seq Inner))
-> IO (Seq Inner) -> EvalM (Seq Inner)
forall a b. (a -> b) -> a -> b
$ IORef (Seq Inner) -> IO (Seq Inner)
forall a. IORef a -> IO a
readIORef IORef (Seq Inner)
innersRef
  case Seq Inner -> ViewL Inner
forall a. Seq a -> ViewL a
Sq.viewl Seq Inner
inners of
    ViewL Inner
EmptyL -> Bool -> EvalM Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
    ISubCollection ObjectRef
ref' :< Seq Inner
tInners -> do
      Seq Inner
hInners <- ObjectRef -> EvalM WHNFData
evalRef ObjectRef
ref' EvalM WHNFData
-> (WHNFData -> EvalM (Seq Inner)) -> EvalM (Seq Inner)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= WHNFData -> EvalM (Seq Inner)
expandCollection
      IO () -> StateT EvalState (ExceptT EgisonError RuntimeM) ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> StateT EvalState (ExceptT EgisonError RuntimeM) ())
-> IO () -> StateT EvalState (ExceptT EgisonError RuntimeM) ()
forall a b. (a -> b) -> a -> b
$ IORef (Seq Inner) -> Seq Inner -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (Seq Inner)
innersRef (Seq Inner
hInners Seq Inner -> Seq Inner -> Seq Inner
forall a. Seq a -> Seq a -> Seq a
>< Seq Inner
tInners)
      WHNFData -> EvalM Bool
isEmptyCollection WHNFData
coll
    ViewL Inner
_ -> Bool -> EvalM Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
isEmptyCollection WHNFData
_ = Bool -> EvalM Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False

unconsCollection :: WHNFData -> MatchM (ObjectRef, ObjectRef)
unconsCollection :: WHNFData -> MatchM (ObjectRef, ObjectRef)
unconsCollection (Value (Collection Seq EgisonValue
col)) =
  case Seq EgisonValue -> ViewL EgisonValue
forall a. Seq a -> ViewL a
Sq.viewl Seq EgisonValue
col of
    ViewL EgisonValue
EmptyL -> MatchM (ObjectRef, ObjectRef)
forall a. MatchM a
matchFail
    EgisonValue
val :< Seq EgisonValue
vals ->
      StateT
  EvalState (ExceptT EgisonError RuntimeM) (ObjectRef, ObjectRef)
-> MatchM (ObjectRef, ObjectRef)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (StateT
   EvalState (ExceptT EgisonError RuntimeM) (ObjectRef, ObjectRef)
 -> MatchM (ObjectRef, ObjectRef))
-> StateT
     EvalState (ExceptT EgisonError RuntimeM) (ObjectRef, ObjectRef)
-> MatchM (ObjectRef, ObjectRef)
forall a b. (a -> b) -> a -> b
$ (,) (ObjectRef -> ObjectRef -> (ObjectRef, ObjectRef))
-> StateT EvalState (ExceptT EgisonError RuntimeM) ObjectRef
-> StateT
     EvalState
     (ExceptT EgisonError RuntimeM)
     (ObjectRef -> (ObjectRef, ObjectRef))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> WHNFData
-> StateT EvalState (ExceptT EgisonError RuntimeM) ObjectRef
newEvaluatedObjectRef (EgisonValue -> WHNFData
Value EgisonValue
val)
                 StateT
  EvalState
  (ExceptT EgisonError RuntimeM)
  (ObjectRef -> (ObjectRef, ObjectRef))
-> StateT EvalState (ExceptT EgisonError RuntimeM) ObjectRef
-> StateT
     EvalState (ExceptT EgisonError RuntimeM) (ObjectRef, ObjectRef)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> WHNFData
-> StateT EvalState (ExceptT EgisonError RuntimeM) ObjectRef
newEvaluatedObjectRef (EgisonValue -> WHNFData
Value (EgisonValue -> WHNFData) -> EgisonValue -> WHNFData
forall a b. (a -> b) -> a -> b
$ Seq EgisonValue -> EgisonValue
Collection Seq EgisonValue
vals)
unconsCollection coll :: WHNFData
coll@(ICollection IORef (Seq Inner)
innersRef) = do
  Seq Inner
inners <- IO (Seq Inner) -> MaybeT EvalM (Seq Inner)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Seq Inner) -> MaybeT EvalM (Seq Inner))
-> IO (Seq Inner) -> MaybeT EvalM (Seq Inner)
forall a b. (a -> b) -> a -> b
$ IORef (Seq Inner) -> IO (Seq Inner)
forall a. IORef a -> IO a
readIORef IORef (Seq Inner)
innersRef
  case Seq Inner -> ViewL Inner
forall a. Seq a -> ViewL a
Sq.viewl Seq Inner
inners of
    ViewL Inner
EmptyL -> MatchM (ObjectRef, ObjectRef)
forall a. MatchM a
matchFail
    IElement ObjectRef
ref' :< Seq Inner
tInners -> do
      IORef (Seq Inner)
tInnersRef <- IO (IORef (Seq Inner)) -> MaybeT EvalM (IORef (Seq Inner))
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (IORef (Seq Inner)) -> MaybeT EvalM (IORef (Seq Inner)))
-> IO (IORef (Seq Inner)) -> MaybeT EvalM (IORef (Seq Inner))
forall a b. (a -> b) -> a -> b
$ Seq Inner -> IO (IORef (Seq Inner))
forall a. a -> IO (IORef a)
newIORef Seq Inner
tInners
      StateT
  EvalState (ExceptT EgisonError RuntimeM) (ObjectRef, ObjectRef)
-> MatchM (ObjectRef, ObjectRef)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (StateT
   EvalState (ExceptT EgisonError RuntimeM) (ObjectRef, ObjectRef)
 -> MatchM (ObjectRef, ObjectRef))
-> StateT
     EvalState (ExceptT EgisonError RuntimeM) (ObjectRef, ObjectRef)
-> MatchM (ObjectRef, ObjectRef)
forall a b. (a -> b) -> a -> b
$ (ObjectRef
ref', ) (ObjectRef -> (ObjectRef, ObjectRef))
-> StateT EvalState (ExceptT EgisonError RuntimeM) ObjectRef
-> StateT
     EvalState (ExceptT EgisonError RuntimeM) (ObjectRef, ObjectRef)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> WHNFData
-> StateT EvalState (ExceptT EgisonError RuntimeM) ObjectRef
newEvaluatedObjectRef (IORef (Seq Inner) -> WHNFData
ICollection IORef (Seq Inner)
tInnersRef)
    ISubCollection ObjectRef
ref' :< Seq Inner
tInners -> do
      Seq Inner
hInners <- EvalM (Seq Inner) -> MaybeT EvalM (Seq Inner)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (EvalM (Seq Inner) -> MaybeT EvalM (Seq Inner))
-> EvalM (Seq Inner) -> MaybeT EvalM (Seq Inner)
forall a b. (a -> b) -> a -> b
$ ObjectRef -> EvalM WHNFData
evalRef ObjectRef
ref' EvalM WHNFData
-> (WHNFData -> EvalM (Seq Inner)) -> EvalM (Seq Inner)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= WHNFData -> EvalM (Seq Inner)
expandCollection
      IO () -> MaybeT EvalM ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> MaybeT EvalM ()) -> IO () -> MaybeT EvalM ()
forall a b. (a -> b) -> a -> b
$ IORef (Seq Inner) -> Seq Inner -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (Seq Inner)
innersRef (Seq Inner
hInners Seq Inner -> Seq Inner -> Seq Inner
forall a. Seq a -> Seq a -> Seq a
>< Seq Inner
tInners)
      WHNFData -> MatchM (ObjectRef, ObjectRef)
unconsCollection WHNFData
coll
unconsCollection WHNFData
_ = MatchM (ObjectRef, ObjectRef)
forall a. MatchM a
matchFail

unsnocCollection :: WHNFData -> MatchM (ObjectRef, ObjectRef)
unsnocCollection :: WHNFData -> MatchM (ObjectRef, ObjectRef)
unsnocCollection (Value (Collection Seq EgisonValue
col)) =
  case Seq EgisonValue -> ViewR EgisonValue
forall a. Seq a -> ViewR a
Sq.viewr Seq EgisonValue
col of
    ViewR EgisonValue
EmptyR -> MatchM (ObjectRef, ObjectRef)
forall a. MatchM a
matchFail
    Seq EgisonValue
vals :> EgisonValue
val ->
      StateT
  EvalState (ExceptT EgisonError RuntimeM) (ObjectRef, ObjectRef)
-> MatchM (ObjectRef, ObjectRef)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (StateT
   EvalState (ExceptT EgisonError RuntimeM) (ObjectRef, ObjectRef)
 -> MatchM (ObjectRef, ObjectRef))
-> StateT
     EvalState (ExceptT EgisonError RuntimeM) (ObjectRef, ObjectRef)
-> MatchM (ObjectRef, ObjectRef)
forall a b. (a -> b) -> a -> b
$ (,) (ObjectRef -> ObjectRef -> (ObjectRef, ObjectRef))
-> StateT EvalState (ExceptT EgisonError RuntimeM) ObjectRef
-> StateT
     EvalState
     (ExceptT EgisonError RuntimeM)
     (ObjectRef -> (ObjectRef, ObjectRef))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> WHNFData
-> StateT EvalState (ExceptT EgisonError RuntimeM) ObjectRef
newEvaluatedObjectRef (EgisonValue -> WHNFData
Value (EgisonValue -> WHNFData) -> EgisonValue -> WHNFData
forall a b. (a -> b) -> a -> b
$ Seq EgisonValue -> EgisonValue
Collection Seq EgisonValue
vals)
                 StateT
  EvalState
  (ExceptT EgisonError RuntimeM)
  (ObjectRef -> (ObjectRef, ObjectRef))
-> StateT EvalState (ExceptT EgisonError RuntimeM) ObjectRef
-> StateT
     EvalState (ExceptT EgisonError RuntimeM) (ObjectRef, ObjectRef)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> WHNFData
-> StateT EvalState (ExceptT EgisonError RuntimeM) ObjectRef
newEvaluatedObjectRef (EgisonValue -> WHNFData
Value EgisonValue
val)
unsnocCollection coll :: WHNFData
coll@(ICollection IORef (Seq Inner)
innersRef) = do
  Seq Inner
inners <- IO (Seq Inner) -> MaybeT EvalM (Seq Inner)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Seq Inner) -> MaybeT EvalM (Seq Inner))
-> IO (Seq Inner) -> MaybeT EvalM (Seq Inner)
forall a b. (a -> b) -> a -> b
$ IORef (Seq Inner) -> IO (Seq Inner)
forall a. IORef a -> IO a
readIORef IORef (Seq Inner)
innersRef
  case Seq Inner -> ViewR Inner
forall a. Seq a -> ViewR a
Sq.viewr Seq Inner
inners of
    ViewR Inner
EmptyR -> MatchM (ObjectRef, ObjectRef)
forall a. MatchM a
matchFail
    Seq Inner
hInners :> IElement ObjectRef
ref' -> do
      IORef (Seq Inner)
hInnersRef <- IO (IORef (Seq Inner)) -> MaybeT EvalM (IORef (Seq Inner))
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (IORef (Seq Inner)) -> MaybeT EvalM (IORef (Seq Inner)))
-> IO (IORef (Seq Inner)) -> MaybeT EvalM (IORef (Seq Inner))
forall a b. (a -> b) -> a -> b
$ Seq Inner -> IO (IORef (Seq Inner))
forall a. a -> IO (IORef a)
newIORef Seq Inner
hInners
      StateT
  EvalState (ExceptT EgisonError RuntimeM) (ObjectRef, ObjectRef)
-> MatchM (ObjectRef, ObjectRef)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (StateT
   EvalState (ExceptT EgisonError RuntimeM) (ObjectRef, ObjectRef)
 -> MatchM (ObjectRef, ObjectRef))
-> StateT
     EvalState (ExceptT EgisonError RuntimeM) (ObjectRef, ObjectRef)
-> MatchM (ObjectRef, ObjectRef)
forall a b. (a -> b) -> a -> b
$ (, ObjectRef
ref') (ObjectRef -> (ObjectRef, ObjectRef))
-> StateT EvalState (ExceptT EgisonError RuntimeM) ObjectRef
-> StateT
     EvalState (ExceptT EgisonError RuntimeM) (ObjectRef, ObjectRef)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> WHNFData
-> StateT EvalState (ExceptT EgisonError RuntimeM) ObjectRef
newEvaluatedObjectRef (IORef (Seq Inner) -> WHNFData
ICollection IORef (Seq Inner)
hInnersRef)
    Seq Inner
hInners :> ISubCollection ObjectRef
ref' -> do
      Seq Inner
tInners <- EvalM (Seq Inner) -> MaybeT EvalM (Seq Inner)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (EvalM (Seq Inner) -> MaybeT EvalM (Seq Inner))
-> EvalM (Seq Inner) -> MaybeT EvalM (Seq Inner)
forall a b. (a -> b) -> a -> b
$ ObjectRef -> EvalM WHNFData
evalRef ObjectRef
ref' EvalM WHNFData
-> (WHNFData -> EvalM (Seq Inner)) -> EvalM (Seq Inner)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= WHNFData -> EvalM (Seq Inner)
expandCollection
      IO () -> MaybeT EvalM ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> MaybeT EvalM ()) -> IO () -> MaybeT EvalM ()
forall a b. (a -> b) -> a -> b
$ IORef (Seq Inner) -> Seq Inner -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (Seq Inner)
innersRef (Seq Inner
hInners Seq Inner -> Seq Inner -> Seq Inner
forall a. Seq a -> Seq a -> Seq a
>< Seq Inner
tInners)
      WHNFData -> MatchM (ObjectRef, ObjectRef)
unsnocCollection WHNFData
coll
unsnocCollection WHNFData
_ = MatchM (ObjectRef, ObjectRef)
forall a. MatchM a
matchFail

collectionToRefs :: WHNFData -> EvalM (MList EvalM ObjectRef)
collectionToRefs :: WHNFData -> EvalM (MList EvalM ObjectRef)
collectionToRefs (Value (Collection Seq EgisonValue
vals)) =
  if Seq EgisonValue -> Bool
forall a. Seq a -> Bool
Sq.null Seq EgisonValue
vals then MList EvalM ObjectRef -> EvalM (MList EvalM ObjectRef)
forall (m :: * -> *) a. Monad m => a -> m a
return MList EvalM ObjectRef
forall (m :: * -> *) a. MList m a
MNil
                  else Seq ObjectRef -> MList EvalM ObjectRef
forall (m :: * -> *) a. Monad m => Seq a -> MList m a
fromSeq (Seq ObjectRef -> MList EvalM ObjectRef)
-> StateT EvalState (ExceptT EgisonError RuntimeM) (Seq ObjectRef)
-> EvalM (MList EvalM ObjectRef)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (EgisonValue
 -> StateT EvalState (ExceptT EgisonError RuntimeM) ObjectRef)
-> Seq EgisonValue
-> StateT EvalState (ExceptT EgisonError RuntimeM) (Seq ObjectRef)
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (WHNFData
-> StateT EvalState (ExceptT EgisonError RuntimeM) ObjectRef
newEvaluatedObjectRef (WHNFData
 -> StateT EvalState (ExceptT EgisonError RuntimeM) ObjectRef)
-> (EgisonValue -> WHNFData)
-> EgisonValue
-> StateT EvalState (ExceptT EgisonError RuntimeM) ObjectRef
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EgisonValue -> WHNFData
Value) Seq EgisonValue
vals
collectionToRefs whnf :: WHNFData
whnf@(ICollection IORef (Seq Inner)
_) = do
  Bool
isEmpty <- WHNFData -> EvalM Bool
isEmptyCollection WHNFData
whnf
  if Bool
isEmpty
    then MList EvalM ObjectRef -> EvalM (MList EvalM ObjectRef)
forall (m :: * -> *) a. Monad m => a -> m a
return MList EvalM ObjectRef
forall (m :: * -> *) a. MList m a
MNil
    else do
      (ObjectRef
head, ObjectRef
tail) <- Maybe (ObjectRef, ObjectRef) -> (ObjectRef, ObjectRef)
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe (ObjectRef, ObjectRef) -> (ObjectRef, ObjectRef))
-> EvalM (Maybe (ObjectRef, ObjectRef))
-> StateT
     EvalState (ExceptT EgisonError RuntimeM) (ObjectRef, ObjectRef)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MatchM (ObjectRef, ObjectRef)
-> EvalM (Maybe (ObjectRef, ObjectRef))
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT (WHNFData -> MatchM (ObjectRef, ObjectRef)
unconsCollection WHNFData
whnf)
      WHNFData
tail' <- ObjectRef -> EvalM WHNFData
evalRef ObjectRef
tail
      MList EvalM ObjectRef -> EvalM (MList EvalM ObjectRef)
forall (m :: * -> *) a. Monad m => a -> m a
return (MList EvalM ObjectRef -> EvalM (MList EvalM ObjectRef))
-> MList EvalM ObjectRef -> EvalM (MList EvalM ObjectRef)
forall a b. (a -> b) -> a -> b
$ ObjectRef -> EvalM (MList EvalM ObjectRef) -> MList EvalM ObjectRef
forall (m :: * -> *) a. a -> m (MList m a) -> MList m a
MCons ObjectRef
head (WHNFData -> EvalM (MList EvalM ObjectRef)
collectionToRefs WHNFData
tail')
collectionToRefs WHNFData
whnf = (CallStack -> EgisonError) -> EvalM (MList EvalM ObjectRef)
forall a. (CallStack -> EgisonError) -> EvalM a
throwErrorWithTrace (String -> WHNFData -> CallStack -> EgisonError
TypeMismatch String
"collection" WHNFData
whnf)

collectionToList :: EgisonValue -> EvalM [EgisonValue]
collectionToList :: EgisonValue -> EvalM [EgisonValue]
collectionToList (Collection Seq EgisonValue
sq) = [EgisonValue] -> EvalM [EgisonValue]
forall (m :: * -> *) a. Monad m => a -> m a
return ([EgisonValue] -> EvalM [EgisonValue])
-> [EgisonValue] -> EvalM [EgisonValue]
forall a b. (a -> b) -> a -> b
$ Seq EgisonValue -> [EgisonValue]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList Seq EgisonValue
sq
collectionToList EgisonValue
val             = (CallStack -> EgisonError) -> EvalM [EgisonValue]
forall a. (CallStack -> EgisonError) -> EvalM a
throwErrorWithTrace (String -> WHNFData -> CallStack -> EgisonError
TypeMismatch String
"collection" (EgisonValue -> WHNFData
Value EgisonValue
val))

makeICollection :: [WHNFData] -> EvalM WHNFData
makeICollection :: [WHNFData] -> EvalM WHNFData
makeICollection [WHNFData]
xs  = do
  [Inner]
is <- (WHNFData -> StateT EvalState (ExceptT EgisonError RuntimeM) Inner)
-> [WHNFData]
-> StateT EvalState (ExceptT EgisonError RuntimeM) [Inner]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (\WHNFData
x -> ObjectRef -> Inner
IElement (ObjectRef -> Inner)
-> StateT EvalState (ExceptT EgisonError RuntimeM) ObjectRef
-> StateT EvalState (ExceptT EgisonError RuntimeM) Inner
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> WHNFData
-> StateT EvalState (ExceptT EgisonError RuntimeM) ObjectRef
newEvaluatedObjectRef WHNFData
x) [WHNFData]
xs
  IORef (Seq Inner)
v <- IO (IORef (Seq Inner))
-> StateT
     EvalState (ExceptT EgisonError RuntimeM) (IORef (Seq Inner))
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (IORef (Seq Inner))
 -> StateT
      EvalState (ExceptT EgisonError RuntimeM) (IORef (Seq Inner)))
-> IO (IORef (Seq Inner))
-> StateT
     EvalState (ExceptT EgisonError RuntimeM) (IORef (Seq Inner))
forall a b. (a -> b) -> a -> b
$ Seq Inner -> IO (IORef (Seq Inner))
forall a. a -> IO (IORef a)
newIORef (Seq Inner -> IO (IORef (Seq Inner)))
-> Seq Inner -> IO (IORef (Seq Inner))
forall a b. (a -> b) -> a -> b
$ [Inner] -> Seq Inner
forall a. [a] -> Seq a
Sq.fromList [Inner]
is
  WHNFData -> EvalM WHNFData
forall (m :: * -> *) a. Monad m => a -> m a
return (WHNFData -> EvalM WHNFData) -> WHNFData -> EvalM WHNFData
forall a b. (a -> b) -> a -> b
$ IORef (Seq Inner) -> WHNFData
ICollection IORef (Seq Inner)
v