@@ -16,12 +16,15 @@ module Task
1616 shiftDataL,
1717 readData,
1818 writeData,
19+ readCommand,
1920 executeCommand,
2021 evaluateProgram,
2122 executeProgram,
2223 )
2324where
2425
26+import Data.Char
27+
2528-- ____ _____ _ _ _
2629-- | __ )| ___| (_)_ __ | |_ ___ _ __ _ __ _ __ ___| |_ ___ _ __
2730-- | _ \| |_ | | '_ \| __/ _ \ '__| '_ \| '__/ _ \ __/ _ \ '__|
@@ -63,7 +66,25 @@ data Tape a
6366 tapeValue :: a,
6467 rightTape :: [a]
6568 }
66โ deriving (Eq, Ord, Show)
69+ deriving (Eq, Ord)
70+
71+instance Show a => Show (Tape a) where
72+ show (Tape l c right) = show (reverse (take 5 l)) <> " " <> show c <> " " <> show (take 5 right)
73+
74+-- | Creates a tape from a list.
75+--
76+-- Note that the tape will be empty to the left.
77+--
78+-- >>> initializeTape [1, 5, 8, ...]
79+--
80+-- โโโโฌโโโโโโฌโโโโโโฌโโโโโโฌโโโโโโฌโโโถ
81+-- ... โ โ 1 โ 5 โ 8 โ ...
82+-- โโโโดโโโโโโดโโโโโโดโโโโโโดโโโโโโดโโโถ
83+-- โฒ
84+-- โ
85+initializeTape :: [a] -> Maybe (Tape a)
86+initializeTape [] = Nothing
87+initializeTape (a : aa) = Just (Tape [] a aa)
6788
6889-- | This is represents the operation of moving the tape pointer to the left.
6990shiftTapeL :: Tape a -> Maybe (Tape a)
@@ -102,6 +123,11 @@ instance Functor (ErrorState e s) where
102123
103124instance Applicative (ErrorState e s) where
104125 pure = error "TODO: Applicative (ErrorState e s) - pure"
126+
127+ -- NOTE: State from the left hand side should be passed to the right hand
128+ -- side.
129+ -- Conversely the state from the right hand side should be the state of the
130+ -- output.
105131 (<*>) = error "TODO: Applicative (ErrorState e s) - (<*>)"
106132
107133instance Monad (ErrorState e s) where
@@ -120,7 +146,7 @@ throwError :: e -> ErrorState e s a
120146throwError = error "TODO: throwError"
121147
122148-- | This operations allows you to encapsulate the process of reading the state,
123โ-- modifying it and writing it into the monad into a single operation.
149+-- modifying it and writing it into the monad in a single operation.
124150--
125151-- It should modify the current state with the given function.
126152modify :: (s -> s) -> ErrorState e s ()
@@ -160,6 +186,10 @@ type BFMonad a = ErrorState BFError BFState a
160186
161187-- | This operation should consume one 'Char' from the input stream
162188-- and return it.
189+--
190+-- Should throw 'NotEnoughInput' error when the input stream is empty.
191+--
192+-- HINT: From now on it would be easier to use `do`-syntax.
163193readInput :: BFMonad Char
164194readInput = error "TODO: readInput"
165195
@@ -217,6 +247,9 @@ readData = error "TODO: readData"
217247writeData :: Char -> BFMonad ()
218248writeData = error "TODO: writeData"
219249
250+readCommand :: BFMonad BFCommand
251+readCommand = error "TODO: readCommand"
252+
220253-- _____ _ _ _ _
221254-- |_ _| |_ ___ (_)_ _| |_ ___ _ _ _ __ _ _ ___| |_ ___ _ _
222255-- | | | ' \/ -_) | | ' \ _/ -_) '_| '_ \ '_/ -_) _/ -_) '_|
@@ -230,8 +263,6 @@ writeData = error "TODO: writeData"
230263-- Please have a look at this commands table:
231264-- https://en.wikipedia.org/wiki/Brainfuck#Commands
232265--
233โ-- To increment and decrement a `Char` you can use `succ` and `pred`.
234โ--
235266-- Note: non-command characters are ignored.
236267executeCommand :: BFCommand -> BFMonad CommandResult
237268executeCommand = error "TODO: executeCommand"
@@ -266,5 +297,9 @@ emptyTape = Tape (repeat zeroChar) zeroChar (repeat zeroChar)
266297-- You will need to construct the initial state for the monad, evaluate the
267298-- program from the initial state, and convert the resulting value to the
268299-- appropriate type.
300+--
301+-- You can use these two functions to convert between 'Char' and 'Int':
302+-- ord :: Char -> Int
303+-- chr :: Int -> Char
269304executeProgram :: [BFCommand] -> String -> Maybe String
270305executeProgram = error "TODO: executeProgram"