ideas-1.0: src/Service/State.hs
-----------------------------------------------------------------------------
-- Copyright 2011, Open Universiteit Nederland. This file is distributed
-- under the terms of the GNU General Public License. For more information,
-- see the file "LICENSE.txt", which is included in the distribution.
-----------------------------------------------------------------------------
-- |
-- Maintainer : bastiaan.heeren@ou.nl
-- Stability : provisional
-- Portability : portable (depends on ghc)
--
-- The information maintained for a learner trying to complete a
-- derivation.
--
-----------------------------------------------------------------------------
module Service.State
( -- * Exercise state
State, makeState, empyStateContext, emptyState
, exercise, statePrefix, stateContext, stateTerm
-- * Types
, stateType
) where
import Common.Library
import Common.Utils (readM)
import Data.Maybe
import Service.Types
data State a = State
{ exercise :: Exercise a
, statePrefix :: Maybe (Prefix (Context a))
, stateContext :: Context a
}
instance Show (State a) where
show s = unlines $ "State {" : map (" "++) xs ++ ["}"]
where
xs = [ "exercise = " ++ showId s
, "prefix = " ++ maybe "no prefix" show (statePrefix s)
, "steps = " ++ maybe "no prefix" (show . prefixToSteps) (statePrefix s)
, "term = " ++ prettyPrinterContext (exercise s) (stateContext s)
]
instance HasId (State a) where
getId = getId . exercise
changeId f s = s { exercise = changeId f (exercise s) }
stateTerm :: State a -> a
stateTerm = fromMaybe (error "invalid term") . fromContext . stateContext
-----------------------------------------------------------
makeState :: Exercise a -> Maybe (Prefix (Context a)) -> Context a -> State a
makeState = State
empyStateContext :: Exercise a -> Context a -> State a
empyStateContext ex = makeState ex (Just pr)
where
pr = emptyPrefix (strategy ex)
emptyState :: Exercise a -> a -> State a
emptyState ex = empyStateContext ex . inContext ex
--------------------------------------------------------------
stateType :: Type a (State a)
stateType = Tag "state" (Iso (f <-> g) tp)
where
f (ex, mp, ctx) =
let str = strategy ex
h = fromMaybe [] . readM
in makeState ex (mp >>= flip makePrefix str . h) ctx
g st =
( exercise st
, fmap show (statePrefix st)
, stateContext st
)
tp = tuple3 Exercise prefixType Context
-- iso prevents that prefix is turned into an (XML) attribute
prefixType = maybeType (Tag "prefix" (Iso identity String))