codesnippets:statemonads
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| codesnippets:statemonads [2021/05/03 21:50] – [A decoder] f2b216 | codesnippets:statemonads [2025/10/08 00:48] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| ====== State monads ====== | ====== State monads ====== | ||
| - | ~~DISCUSSION ~~ | ||
| * inspired by [[http:// | * inspired by [[http:// | ||
| Line 309: | Line 308: | ||
| * example | * example | ||
| - | * to show how a decoder can be designed | + | * to show how a decoder can be designed |
| * to take symbols that influence the amount of the following reading | * to take symbols that influence the amount of the following reading | ||
| * compiles | * compiles | ||
| Line 323: | Line 322: | ||
| main = | main = | ||
| do | do | ||
| - | -- +-take | + | -- |
| - | -- | + | -- + - take the next 4 characters converted |
| - | -- | + | -- / + - take the next 3 Integer |
| - | -- | + | -- / / + - take the next 13 characters converted to Integer |
| - | -- | + | -- / |
| - | print ((parse 3 " | + | -- / / / / |
| + | -- / | ||
| + | -- / | ||
| + | -- v | ||
| + | print ((decode " | ||
| - | type DecodeState = (Integer, | + | type DecodeState = [Char] -- the remaining chars |
| class Decoder tValue where | class Decoder tValue where | ||
| - | | + | |
| - | | + | |
| - | | + | decodeMaybeS :: S.State DecodeState (Maybe tValue) |
| - | + | | |
| - | instance Decoder Integer where | + | |
| - | | + | |
| do | do | ||
| - | | + | nCount <- takeRepetitionCountS |
| - | liValues <- parseS' | + | liValues <- decodeNListS |
| return liValues | return liValues | ||
| - | where | + | decodeNListS |
| - | parseS' | + | |
| - | | + | | lCount > 0 = |
| - | | lCount' | + | do |
| + | mx <- decodeMaybeS | ||
| + | Sfr.ifJust mx | ||
| + | {- then -} (\x -> | ||
| + | do | ||
| + | liValues <- decodeNListS (lCount - 1) | ||
| + | return (x : liValues)) | ||
| + | {- else -} (return []) | ||
| + | | otherwise = return [] | ||
| + | |||
| + | data MyData = MyData Integer [Integer] Double | ||
| + | deriving Show | ||
| + | |||
| + | instance Decoder MyData where | ||
| + | decodeMaybeS = | ||
| + | do | ||
| + | mn1 <- decodeMaybeS | ||
| + | Sfr.ifJust mn1 | ||
| + | {- then -} (\n1 -> | ||
| do | do | ||
| - | | + | |
| - | | + | |
| - | Sfr.ifJust | + | Sfr.ifJust |
| - | {- then -} (\x -> return (x : liValues)) | + | {- then -} (\n3 -> return (Just (MyData n1 ln2 n3))) |
| - | {- else -} (return | + | {- else -} (return |
| - | | otherwise = return [] | + | ) |
| - | parseS'' | + | |
| - | parseS'' | + | |
| - | | + | |
| - | mch <- takeMaybeCharS | + | |
| - | miValue <- parseS''' | + | |
| - | return miValue | + | |
| - | parseS''' | + | |
| - | parseS''' | + | |
| - | parseS''' | + | |
| - | do | + | |
| - | nLength <- pure ((read [ch]) :: Integer) | + | |
| - | lch <- takeCharListS nLength | + | |
| - | if (Sfr.len lch) > 0 | + | |
| - | then return (Just ((read lch) :: Integer)) | + | |
| - | else return Nothing | + | |
| - | eatCh :: Integer -> (Integer, [Char]) -> (Integer, [Char]) | + | instance Decoder Integer where |
| - | eatCh _ (n, []) = (n, []) | + | decodeMaybeS = |
| - | eatCh nCount | + | do |
| - | | nCount > 0 = eatCh (nCount - 1) ((n - 1), lrch) | + | nLength <- takeRepetitionCountS |
| - | | otherwise | + | lch <- takeCharListS nLength |
| + | if (Sfr.len lch) > 0 | ||
| + | then return (Just ((read lch) :: Integer)) | ||
| + | else return Nothing | ||
| + | |||
| + | instance Decoder Double where | ||
| + | decodeMaybeS = | ||
| + | do | ||
| + | nLength <- takeRepetitionCountS | ||
| + | lch <- takeCharListS nLength | ||
| + | if (Sfr.len lch) > 0 | ||
| + | then return | ||
| + | else return Nothing | ||
| + | |||
| + | takeRepetitionCountS :: S.State DecodeState | ||
| + | takeRepetitionCountS = | ||
| + | do | ||
| + | mch <- takeMaybeCharS | ||
| + | if mch == (Just ' | ||
| + | then takeRepetitionCountS' | ||
| + | else return 0 | ||
| + | where | ||
| + | takeRepetitionCountS' | ||
| + | takeRepetitionCountS' | ||
| + | do | ||
| + | lch <- takeUntilS ':' | ||
| + | nCount <- pure ((read lch) :: Integer) | ||
| + | return nCount | ||
| + | |||
| + | takeUntilS :: Char -> S.State DecodeState | ||
| + | takeUntilS ch = | ||
| + | do | ||
| + | mch <- takeMaybeCharS | ||
| + | if mch == (Just ch) | ||
| + | then return [] | ||
| + | else | ||
| + | Sfr.ifJust mch | ||
| + | {- then -} (\ch' | ||
| + | do | ||
| + | lch <- takeUntilS ch | ||
| + | return | ||
| + | {- else -} (return []) | ||
| + | |||
| + | eatCh :: Integer | ||
| + | eatCh _ [] = [] | ||
| + | eatCh nCount lch@(_: | ||
| + | | nCount > 0 = eatCh (nCount - 1) lrch | ||
| + | | otherwise | ||
| - | mchGet :: (Integer, | + | mchGet :: [Char] -> (Maybe Char) |
| - | mchGet | + | mchGet [] = Nothing |
| - | mchGet | + | mchGet (ch:_) = Just ch |
| - | lchGet :: Integer -> (Integer, | + | lchGet :: Integer -> [Char] -> [Char] |
| - | lchGet _ (_, []) = [] | + | lchGet _ [] = [] |
| - | lchGet nCount | + | lchGet nCount (ch:lrch) |
| - | | nCount > 0 = ch : (lchGet (nCount - 1) ((n - 1), lrch)) | + | | nCount > 0 = ch : (lchGet (nCount - 1) lrch) |
| | otherwise | | otherwise | ||
| Line 430: | Line 483: | ||
| </ | </ | ||
| * executes, with output:< | * executes, with output:< | ||
| - | [12345,12,123] | + | Just (MyData 4736 [7364537284958, |
| </ | </ | ||
| + | |||
| + | |||
| + | ===== ✎ ===== | ||
| + | ~~DISCUSSION~~ | ||
codesnippets/statemonads.1620071455.txt.gz · Last modified: (external edit)
