aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/Reducer.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Reducer.hs')
-rw-r--r--src/Reducer.hs41
1 files changed, 22 insertions, 19 deletions
diff --git a/src/Reducer.hs b/src/Reducer.hs
index 82de067..8823b3c 100644
--- a/src/Reducer.hs
+++ b/src/Reducer.hs
@@ -9,6 +9,7 @@ import Data.List ( elemIndex )
import Data.Map ( Map )
import qualified Data.Map as Map
import Helper
+import System.IO.Unsafe ( unsafePerformIO )
import System.Random ( randomIO )
type Store = Map Int Box
@@ -20,30 +21,32 @@ data Rvar = Num Int | Hole
data Redex = Rabs Int Redex | Rapp Redex Redex | Rvar Rvar | Rclosure Redex Store | Rcache Box Redex
data Conf = Econf Redex Store Stack | Cconf Stack Redex | End
-toRedex :: Expression -> IO Redex
+-- TODO: unsafePerformIO is very unpure and ugly!! Unfortunately IO seems to
+-- make this function and therefore the entire reduction strict :/
+toRedex :: Expression -> Redex
toRedex = convertWorker []
where
- convertWorker ns (Abstraction e) = do
- v <- randomIO :: IO Int
- t <- convertWorker (v : ns) e
- pure $ Rabs v t
- convertWorker ns (Application l r) = do
- lhs <- convertWorker ns l
- rhs <- convertWorker ns r
- pure $ Rapp lhs rhs
+ convertWorker ns (Abstraction e) =
+ let v = unsafePerformIO randomIO :: Int
+ t = convertWorker (v : ns) e
+ in Rabs v t
+ convertWorker ns (Application l r) =
+ let lhs = convertWorker ns l
+ rhs = convertWorker ns r
+ in Rapp lhs rhs
convertWorker ns (Bruijn i) =
- pure $ Rvar $ Num (if i < 0 || i >= length ns then i else ns !! i)
+ Rvar $ Num (if i < 0 || i >= length ns then i else ns !! i)
convertWorker _ _ = invalidProgramState
-fromRedex :: Redex -> IO Expression
+fromRedex :: Redex -> Expression
fromRedex = convertWorker []
where
- convertWorker es (Rabs n e) = Abstraction <$> convertWorker (n : es) e
- convertWorker es (Rapp l r) = do
- lhs <- convertWorker es l
- rhs <- convertWorker es r
- pure $ Application lhs rhs
- convertWorker es (Rvar (Num n)) = pure $ Bruijn $ maybe n id (elemIndex n es)
+ convertWorker es (Rabs n e) = Abstraction $ convertWorker (n : es) e
+ convertWorker es (Rapp l r) =
+ let lhs = convertWorker es l
+ rhs = convertWorker es r
+ in Application lhs rhs
+ convertWorker es (Rvar (Num n)) = Bruijn $ maybe n id (elemIndex n es)
convertWorker _ _ = invalidProgramState
transition :: Conf -> IO Conf
@@ -95,7 +98,7 @@ loadTerm t = Econf t Map.empty []
reduce :: Expression -> IO Expression
reduce e = do
- redex <- toRedex e
+ redex <- pure $ toRedex e
forEachState (loadTerm redex) transition >>= \case
- Cconf [] v -> fromRedex v
+ Cconf [] v -> pure $ fromRedex v
_ -> invalidProgramState