├── .gitignore ├── Algorithms.cabal ├── Data ├── Infinitable.hs └── Tree │ ├── Binary.hs │ ├── RandomTreap.hs │ └── Treap.hs ├── Haskell-Algorithms.cabal ├── LICENSE ├── Materials ├── Back to the Future - Tech Talks NSU │ ├── Adapter.hs │ ├── Adapter2.hs │ └── Strategy.hs ├── Design and Architecture in FP │ ├── ExistentialAntipattern.hs │ ├── Goals-Simplicity-Requirements.svg │ ├── GoodDesign-1.png │ ├── GoodDesign-2-Problem1.png │ ├── GoodDesign-2-Problem2.png │ ├── GoodDesign-2-Problem3.png │ ├── GoodDesign-2-Problem4.png │ ├── GoodDesign-2.png │ └── WorldCellAdt.hs ├── Game Development Materials.txt ├── Haskell в реальном мире - Статья │ ├── Haskell в реальном мире.txt │ ├── merger 0.13.hs │ ├── merger 0.14.hs │ ├── merger 0.16.hs │ ├── merger 0.23.hs │ ├── parser 0.12.hs │ ├── parser 0.2.hs │ └── parser 0.6.hs └── YAMT │ ├── Mike Vanier's monad tutorial part 1 - Translation.txt │ ├── Mike Vanier's monad tutorial part 2 - Translation.txt │ ├── Mike Vanier's monad tutorial part 3 - Translation.txt │ ├── Mike Vanier's monad tutorial part 4 - Translation.txt │ └── Mike Vanier's monad tutorial part 5 - Translation.txt ├── Programs ├── GameOfLifeComonad │ ├── .gitignore │ ├── GlossMetaLife.hs │ ├── Life.hs │ ├── MetaLife.hs │ ├── SampleCells.hs │ ├── Universe.hs │ ├── config.txt │ ├── run.cmd │ └── run.sh ├── HabrFormat │ ├── .gitignore │ ├── HabrFormat.hs │ ├── article.html │ └── formated_article.html ├── NgnTraffic Old │ ├── LICENSE.GPL3 │ ├── LicenseTemplate.txt │ ├── merger.hs │ └── parser.hs ├── NgnTraffic │ ├── .gitignore │ ├── Constants.hs │ ├── DataProcess.hs │ ├── FileListProcess.hs │ ├── LICENSE.GPL3 │ ├── LicenseTemplate.txt │ ├── NgnTraffic.hs │ ├── Options.hs │ ├── README │ ├── Tools.hs │ └── Types.hs ├── RestCorrecting │ ├── DataProcess.hs │ ├── LicenseTemplate.txt │ ├── README │ ├── RestCorrecting.hs │ ├── Sql.hs │ ├── TestData.hs │ ├── Types.hs │ ├── dbDataTest.txt │ ├── id_obsh.txt │ ├── testResult.txt │ └── updateScripts.sql └── SimpleFormat │ ├── Process.hs │ └── SimpleFormat.hs ├── Prototypes ├── Adv2Game │ ├── Types.hs │ └── Types2.hs ├── BigSpace.EventFlowTree │ ├── Actions.hs │ ├── Event.hs │ ├── EventFlowTree.hs │ ├── Main.hs │ ├── PreGen │ │ └── World.hs │ ├── README │ ├── Tools.hs │ ├── Types.hs │ └── test.txt └── BigSpace.FingerTreeUnstructured │ ├── BigSpace.hs │ └── Type │ ├── Constants.hs │ ├── Event.hs │ ├── EventTree.hs │ ├── Types.hs │ └── Universe.hs ├── Setup.hs ├── Tests ├── .gitignore ├── AppoxyHiringTask │ ├── Lucky.hs │ ├── StringOptimization.hs │ ├── a.txt │ ├── b.txt │ └── lucky.txt ├── ArrowsAndFrees │ ├── ArrEff.hs │ ├── ArrowizedDSL.hs │ ├── ArrowsResearch.hs │ ├── FreeArrows.hs │ ├── FreeDSL.hs │ ├── FreeIODSL.hs │ ├── Hardware.hs │ └── HardwareTypes.hs ├── BinaryTreeWithKeys.hs ├── Combinations.hs ├── Curring.hs ├── Dividing.hs ├── DoNotationTest.hs ├── ExprParsingTest.hs ├── Fact.hs ├── FactAndFib.hs ├── FailureProbability │ ├── FailureProbability.hs │ ├── compile.cmd │ └── run.cmd ├── Fib.hs ├── FinanceTree.hs ├── FizzBuzz.hs ├── FizzBuzz2.hs ├── FizzBuzz3.hs ├── FizzBuzz4.hs ├── FizzBuzz5.hs ├── FizzBuzz6Free.hs ├── Fractal │ ├── .gitignore │ ├── FractalComonad.hs │ ├── FractalOfFrcactals.hs │ └── FractalWithData.hs ├── GameOfLife.hs ├── HaskellSkbRii │ ├── Task1 │ │ ├── FizzBuzz.hs │ │ └── FizzBuzzes.txt │ ├── Task2 │ │ ├── BlankSolver.hs │ │ ├── Solution8.txt │ │ └── TinkAndKiki.hs │ └── Task3 │ │ ├── Interpreter.hs │ │ ├── Language.hs │ │ └── TestInput.txt ├── HighOrderFuncs.hs ├── InfSum.hs ├── Kleisli.hs ├── Language.hs ├── Lessons │ ├── ListFold.hs │ ├── ListMap.hs │ └── Structure.txt ├── ListManipulation.hs ├── LookAndSay.hs ├── Maybe.hs ├── ModuleAbstraction │ ├── Main.hs │ ├── PathFind.hs │ └── PathFind │ │ ├── AStar.hs │ │ └── Dijkstra.hs ├── MonadAbstraction │ ├── Language.hs │ └── StateMonad.hs ├── ParseAndXmlTest.hs ├── ParseAndXmlTest.hs~ ├── Person.xml ├── Phonebook.hs ├── RandomNums.hs ├── ReadWriteFile.hs ├── Robotics │ ├── Task1.hs │ ├── Task2.hs │ └── Task3.hs ├── Rogulike │ ├── ComonadEffectTest.hs │ ├── ComonadEffectTest2.hs │ └── RogueLike.hs ├── STM │ ├── ConcurrentSTM.hs │ ├── StmsMap.hs │ └── philosopers │ │ ├── .gitignore │ │ ├── ChangeLog.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── Setup.hs │ │ ├── app │ │ └── Main.hs │ │ ├── package.yaml │ │ ├── src │ │ ├── Philosophers.hs │ │ ├── Philosophers │ │ │ ├── Log.hs │ │ │ ├── STM.hs │ │ │ ├── Snapshot.hs │ │ │ └── Types.hs │ │ └── Philosophers2 │ │ │ └── STM.hs │ │ ├── stack.yaml │ │ └── test │ │ └── Spec.hs ├── STree.hs ├── ScaleCollect.hs ├── SizeTreap.hs ├── SlyPercents.hs ├── SlyPercents.txt ├── StateInjection │ ├── StateInjectionTest.hs │ └── StateInjectionTest2.hs ├── StateTest.hs ├── StateTransformerTest.hs ├── StateTransformerTest2.hs ├── StringManipulation.hs ├── TH │ ├── WiseConstructor.hs │ └── WiseConstructorTH.hs ├── TestDataGeneration.hs ├── TextRatio.hs ├── TextRatio2.hs ├── TextRatio3.hs ├── Tmp.hs ├── TransitionGraph │ └── transition-graph │ │ ├── .gitignore │ │ ├── ChangeLog.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── Setup.hs │ │ ├── app │ │ ├── AdvGame │ │ │ ├── AdvGameRuntime.hs │ │ │ └── Lang.hs │ │ └── Main.hs │ │ ├── package.yaml │ │ ├── src │ │ ├── Data │ │ │ └── Exists.hs │ │ ├── Lib.hs │ │ └── TransitionGraph │ │ │ ├── Graph.hs │ │ │ ├── Interpreter.hs │ │ │ └── Runtime.hs │ │ ├── stack.yaml │ │ └── test │ │ ├── Spec.hs │ │ └── TransitionGraphSpec.hs ├── TypeClasses │ └── TypeClasses.hs ├── Types │ ├── Command.hs │ ├── Hardware1.hs │ ├── Hardware2.hs │ ├── PhantomTypeCoerce.hs │ ├── PhantomTypeHints.hs │ ├── Test.hs │ ├── TypeCalculation.hs │ ├── TypeFamilies │ │ ├── TypeFamilyTest1.hs │ │ ├── TypeFamilyTest2.hs │ │ └── TypeFamilyTest3.hs │ ├── YonedaLemma.hs │ └── dimensions │ │ ├── LICENSE │ │ ├── README.md │ │ ├── Setup.hs │ │ ├── app │ │ └── Main.hs │ │ ├── dimensions.cabal │ │ ├── src │ │ ├── Dimensions.hs │ │ └── Lib.hs │ │ ├── stack.yaml │ │ └── test │ │ ├── DimensionsSpec.hs │ │ └── Spec.hs ├── XmlParsing │ ├── Main.hs │ ├── Test.hs │ ├── log.xml │ └── test.xml ├── fizzBuzzes.txt ├── myName.txt ├── taggedSymbols.html ├── taggedSymbols.txt ├── taggedSymbols2.html ├── taggedSymbols3.html ├── taggedSymbols4.html ├── test.txt ├── text.txt └── tree.txt └── dist └── setup-config /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | /Programs/BlueFont/p_text.txt 3 | /Programs/BlueFont/text.txt 4 | /Exercises/output.txt 5 | /Exercises/perms2.txt 6 | /Exercises/permutations.txt -------------------------------------------------------------------------------- /Algorithms.cabal: -------------------------------------------------------------------------------- 1 | -- Algorithms.cabal auto-generated by cabal init. For additional 2 | -- options, see 3 | -- http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/authors.html#pkg-descr. 4 | -- The name of the package. 5 | Name: Algorithms 6 | 7 | -- The package version. See the Haskell package versioning policy 8 | -- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for 9 | -- standards guiding when and how versions should be incremented. 10 | Version: 0.0.5 11 | 12 | -- A short (one-line) description of the package. 13 | -- Synopsis: 14 | 15 | -- A longer description of the package. 16 | -- Description: 17 | 18 | -- The license under which the package is released. 19 | License: BSD3 20 | 21 | -- The file containing the license text. 22 | License-file: LICENSE 23 | 24 | -- The package author(s). 25 | Author: Granin, Alexandr 26 | 27 | -- An email address to which users can send suggestions, bug reports, 28 | -- and patches. 29 | Maintainer: graninas@gmail.com 30 | 31 | -- A copyright notice. 32 | -- Copyright: 33 | 34 | Category: Data 35 | 36 | Build-type: Simple 37 | 38 | -- Extra files to be distributed with the package, such as examples or 39 | -- a README. 40 | -- Extra-source-files: 41 | 42 | -- Constraint on the version of Cabal needed to build this package. 43 | Cabal-version: >=1.2 44 | 45 | 46 | Library 47 | -- Modules exported by the library. 48 | Exposed-modules: Examples.SizeTreap, Data.Infinitable, Data.Tree.Treap, Data.Tree.RandomTreap, Data.Tree.BinaryTree 49 | 50 | -- Packages needed in order to build this package. 51 | -- Build-depends: 52 | 53 | -- Modules not exported by this package. 54 | -- Other-modules: 55 | 56 | -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source. 57 | -- Build-tools: 58 | -------------------------------------------------------------------------------- /Data/Infinitable.hs: -------------------------------------------------------------------------------- 1 | {- 2 | By Denis Krjuchkov 3 | http://stackoverflow.com/questions/2354707/in-haskell-is-there-num-a-infinity-a 4 | -} 5 | 6 | module Infinitable where 7 | 8 | data Infinitable a = NegativeInfinity | Regular a | PositiveInfinity 9 | deriving (Eq, Show) 10 | 11 | instance Ord a => Ord (Infinitable a) where 12 | compare NegativeInfinity NegativeInfinity = EQ 13 | compare PositiveInfinity PositiveInfinity = EQ 14 | compare NegativeInfinity _ = LT 15 | compare PositiveInfinity _ = GT 16 | compare _ PositiveInfinity = LT 17 | compare _ NegativeInfinity = GT 18 | compare (Regular x) (Regular y) = compare x y 19 | 20 | main = 21 | let five = Regular 5 22 | pinf = PositiveInfinity::Infinitable Integer 23 | ninf = NegativeInfinity::Infinitable Integer 24 | results = [(pinf > five), (ninf < pinf), (five > ninf)] 25 | in 26 | do putStrLn (show results) 27 | -------------------------------------------------------------------------------- /Data/Tree/Binary.hs: -------------------------------------------------------------------------------- 1 | module Data.Tree.Binary where 2 | 3 | import Prelude hiding (lookup) 4 | 5 | data Ord a => BTree a b = 6 | Leaf 7 | | Branch a b (BTree a b) (BTree a b) 8 | deriving (Show) 9 | 10 | 11 | leaf :: BTree a b 12 | leaf = Leaf 13 | 14 | branch :: Ord a => a -> b -> BTree a b -> BTree a b -> BTree a b 15 | branch = Branch 16 | 17 | left (Branch _ _ l _) = l 18 | right (Branch _ _ _ r) = r 19 | 20 | lookup :: Ord a => a -> BTree a b -> Maybe b 21 | lookup _ Leaf = Nothing 22 | lookup key (Branch k v ltree rtree) | key == k = Just v 23 | | key < k = lookup key ltree 24 | | otherwise = lookup key rtree 25 | 26 | insert :: Ord a => (a, b) -> BTree a b -> BTree a b 27 | insert (key, val) Leaf = Branch key val Leaf Leaf 28 | insert p@(key, val) (Branch k v ltree rtree) | key == k = Branch key val ltree rtree 29 | | key < k = Branch k v (insert p ltree) rtree 30 | | otherwise = Branch k v ltree (insert p rtree) 31 | 32 | minBranch :: Ord a => BTree a b -> BTree a b 33 | minBranch m@(Branch k v Leaf _) = m 34 | minBranch (Branch _ _ l@(Branch _ _ _ _) _) = minBranch l 35 | minBranch _ = Leaf 36 | 37 | delete :: Ord a => a -> BTree a b -> BTree a b 38 | delete _ Leaf = Leaf 39 | delete key (Branch k v ltree Leaf) | key == k = ltree 40 | delete key (Branch k v ltree rtree) | key == k = let mb@(Branch mk mv _ _) = minBranch rtree 41 | in Branch mk mv ltree (delete mk rtree) 42 | | key < k = Branch k v (delete key ltree) rtree 43 | | key > k = Branch k v ltree (delete key ltree) 44 | 45 | fromList :: Ord a => [(a, b)] -> BTree a b 46 | fromList = foldr insert Leaf 47 | 48 | toList :: Ord key => BTree key value -> [(key, value)] 49 | toList Leaf = [] 50 | toList (Branch k v ltree rtree) = ((k, v) : toList ltree) ++ toList rtree -------------------------------------------------------------------------------- /Data/Tree/RandomTreap.hs: -------------------------------------------------------------------------------- 1 | module RandomTreap where 2 | 3 | import qualified Treap as T 4 | import qualified System.Random as R 5 | 6 | newtype RTreap g k p v = RT (g, T.Treap k p v) 7 | deriving Show 8 | 9 | insert :: (R.RandomGen g, Ord a, Enum a, Ord b, Num b, R.Random b) => T.RecalcFunc a b c -> (a, c) -> RTreap g a b c -> RTreap g a b c 10 | insert f (k, v) (RT (g, tree)) = let (p, g') = R.randomR (-1000, 1000) g 11 | in RT (g', T.insert f (k, p, v) tree) 12 | 13 | delete :: (Ord a, Enum a, Ord b) => a -> T.RecalcFunc a b c -> RTreap g a b c -> RTreap g a b c 14 | delete _ _ (RT (g, T.Leaf)) = RT (g, T.Leaf) 15 | delete x0 f (RT (g, tree)) = RT (g, T.delete x0 f tree) 16 | 17 | fromList :: (R.RandomGen g, Ord a, Enum a, Ord b, Num b, R.Random b) => g -> T.RecalcFunc a b c -> [(a, c)] -> RTreap g a b c 18 | fromList g f = foldr (insert f) (RT (g, T.Leaf)) 19 | 20 | toList :: (Ord a, Enum a, Ord b) => RTreap g a b c -> [(a, c)] 21 | toList (RT (_, tree)) = [(k, v) | (k, _, v) <- T.toList tree] 22 | 23 | toSortedListL :: (Ord a, Enum a, Ord b) => RTreap g a b c -> [(a, c)] 24 | toSortedListL (RT (_, tree)) = [(k, v) | (k, _, v) <- T.toSortedListL tree] 25 | 26 | toSortedListR :: (Ord a, Enum a, Ord b) => RTreap g a b c -> [(a, c)] 27 | toSortedListR (RT (_, tree)) = [(k, v) | (k, _, v) <- T.toSortedListR tree] 28 | 29 | val :: (Ord a, Enum a, Ord b) => T.Treap a b Int -> Int 30 | val T.Leaf = 0 31 | val (T.Branch _ _ v _ _) = v 32 | 33 | recalc :: (Ord a, Enum a, Ord b) => T.RecalcFunc a b Int 34 | recalc l r = val l + val r 35 | 36 | testData :: [(Int, Int)] 37 | testData = [(1, 2), (3, 6), (6, 44), (7, 0), (2, 85), (4, -2), (5, 4), (8, 21)] -------------------------------------------------------------------------------- /Data/Tree/Treap.hs: -------------------------------------------------------------------------------- 1 | module Treap where 2 | 3 | import Prelude hiding (lookup) 4 | 5 | data (Ord a, Enum a, Ord b) => Treap a b c = 6 | Leaf 7 | | Branch a b c (Treap a b c) (Treap a b c) 8 | deriving (Show) 9 | 10 | type RecalcFunc a b c = Treap a b c -> Treap a b c -> c 11 | 12 | leaf :: Treap a b c 13 | leaf = Leaf 14 | 15 | branch :: (Ord a, Enum a, Ord b) => a -> b -> c -> Treap a b c -> Treap a b c -> Treap a b c 16 | branch = Branch 17 | 18 | left (Branch _ _ _ l _) = l 19 | right (Branch _ _ _ _ r) = r 20 | 21 | singleton :: (Ord a, Enum a, Ord b) => (a, b, c) -> Treap a b c 22 | singleton (k, p, v) = Branch k p v Leaf Leaf 23 | 24 | merge :: (Ord a, Enum a, Ord b) => RecalcFunc a b c -> Treap a b c -> Treap a b c -> Treap a b c 25 | merge _ Leaf x = x 26 | merge _ x Leaf = x 27 | merge _ (Branch k1 _ _ _ _) (Branch k2 _ _ _ _) | k1 > k2 = undefined 28 | merge f l@(Branch k1 p1 v1 ll lr) r@(Branch k2 p2 v2 rl rr) | p1 > p2 = let subTree = merge f lr r 29 | in Branch k1 p1 (f subTree ll) ll subTree 30 | | p1 <= p2 = let subTree = merge f l rl 31 | in Branch k2 p2 (f subTree rr) subTree rr 32 | 33 | split :: (Ord a, Enum a, Ord b) => a -> RecalcFunc a b c -> Treap a b c -> (Treap a b c, Treap a b c) 34 | split _ _ Leaf = (Leaf, Leaf) 35 | split x0 f (Branch k p v l r) | k <= x0 = let (l', r') = split x0 f r 36 | in (Branch k p (f l l') l l', r') 37 | | k > x0 = let (l', r') = split x0 f l 38 | in (l', Branch k p (f r' r) r' r) 39 | 40 | insert :: (Ord a, Enum a, Ord b) => RecalcFunc a b c -> (a, b, c) -> Treap a b c -> Treap a b c 41 | insert _ (x0, p, v) Leaf = Branch x0 p v Leaf Leaf 42 | insert f (x0, p, v) tree = let (l, r) = split x0 f tree 43 | in merge f (merge f l (Branch x0 p v Leaf Leaf)) r 44 | 45 | delete :: (Ord a, Enum a, Ord b) => a -> RecalcFunc a b c -> Treap a b c -> Treap a b c 46 | delete _ _ Leaf = Leaf 47 | delete x0 f tree = let 48 | (l, r) = split (pred x0) f tree 49 | (l', r') = split x0 f r 50 | in merge f l r' 51 | 52 | lookup :: (Ord a, Enum a, Ord b) => a -> Treap a b c -> Maybe (a, b, c) 53 | lookup k Leaf = Nothing 54 | lookup k (Branch k1 p1 v1 l r) | k == k1 = Just (k1, p1, v1) 55 | | k < k1 = lookup k l 56 | | k > k1 = lookup k r 57 | 58 | fromList :: (Ord a, Enum a, Ord b) => RecalcFunc a b c -> [(a, b, c)] -> Treap a b c 59 | fromList f = foldr (insert f) Leaf 60 | 61 | toList :: (Ord a, Enum a, Ord b) => Treap a b c -> [(a, b, c)] 62 | toList Leaf = [] 63 | toList (Branch k p v l r) = ((k, p, v) : toList l) ++ toList r 64 | 65 | toSortedListL :: (Ord a, Enum a, Ord b) => Treap a b c -> [(a, b, c)] 66 | toSortedListL Leaf = [] 67 | toSortedListL (Branch k p v l r) = toSortedListL l ++ ((k, p, v) : toSortedListL r) 68 | 69 | toSortedListR :: (Ord a, Enum a, Ord b) => Treap a b c -> [(a, b, c)] 70 | toSortedListR Leaf = [] 71 | toSortedListR (Branch k p v l r) = toSortedListR r ++ ((k, p, v) : toSortedListR l) -------------------------------------------------------------------------------- /Haskell-Algorithms.cabal: -------------------------------------------------------------------------------- 1 | -- Haskell-Algorithms.cabal auto-generated by cabal init. For 2 | -- additional options, see 3 | -- http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/authors.html#pkg-descr. 4 | -- The name of the package. 5 | Name: Haskell-Algorithms 6 | 7 | -- The package version. See the Haskell package versioning policy 8 | -- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for 9 | -- standards guiding when and how versions should be incremented. 10 | Version: 0.1 11 | 12 | -- A short (one-line) description of the package. 13 | Synopsis: Algorithms, miniprograms, exercises, prototypes and materials for Haskell learning. 14 | 15 | -- A longer description of the package. 16 | -- Description: 17 | 18 | -- URL for the project homepage or repository. 19 | Homepage: https://github.com/graninas/Haskell-Algorithms 20 | 21 | -- The license under which the package is released. 22 | License: GPL-3 23 | 24 | -- The file containing the license text. 25 | License-file: LICENSE 26 | 27 | -- The package author(s). 28 | Author: Alexandr Granin 29 | 30 | -- An email address to which users can send suggestions, bug reports, 31 | -- and patches. 32 | Maintainer: graninas@gmail.com 33 | 34 | -- A copyright notice. 35 | -- Copyright: 36 | 37 | Category: Algorithms 38 | 39 | Build-type: Simple 40 | 41 | -- Extra files to be distributed with the package, such as examples or 42 | -- a README. 43 | -- Extra-source-files: 44 | 45 | -- Constraint on the version of Cabal needed to build this package. 46 | Cabal-version: >=1.2 47 | 48 | 49 | Library 50 | -- Modules exported by the library. 51 | Exposed-modules: Tests.Kleisli, Prototypes.Adv2Game.Types2, Prototypes.Adv2Game.Types, Programs.NgnTraffic.Types, Programs.NgnTraffic.Tools, Programs.NgnTraffic.Options, Programs.NgnTraffic.NgnTraffic, Programs.NgnTraffic.FileListProcess, Programs.NgnTraffic.DataProcess, Programs.NgnTraffic.Constants, Programs.HabrFormat.HabrFormat, Programs.BlueFont.BlueFont, Exercises.FizzBuzz, Exercises.FinanceTree, Exercises.Dividing, Examples.SizeTreap, Data.Infinitable, Data.Tree.Treap, Data.Tree.RandomTreap, Data.Tree.Binary 52 | 53 | -- Packages needed in order to build this package. 54 | -- Build-depends: 55 | 56 | -- Modules not exported by this package. 57 | -- Other-modules: 58 | 59 | -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source. 60 | -- Build-tools: 61 | -------------------------------------------------------------------------------- /Materials/Back to the Future - Tech Talks NSU/Adapter.hs: -------------------------------------------------------------------------------- 1 | 2 | module Main where 3 | 4 | import qualified Data.Set as Set 5 | 6 | type Node = Int 7 | type Nodes = [Node] 8 | type TableGraph = [ (Node, Nodes) ] 9 | 10 | type Successors = Set.Set Node 11 | type Graph = Node -> Successors 12 | 13 | tarjanAlg :: Graph -> [Nodes] 14 | tarjanAlg = undefined -- some impl 15 | 16 | getNodes n tg = maybe [] id (lookup n tg) 17 | 18 | asGraph :: TableGraph -> Graph 19 | asGraph tg node = Set.fromList succs 20 | where 21 | succs = maybe [] id (lookup node tg) 22 | 23 | asGraph' :: TableGraph -> Graph 24 | asGraph' tg = Set.fromList . flip getNodes tg 25 | 26 | 27 | adaptedTarjanAlg :: TableGraph -> [Nodes] 28 | adaptedTarjanAlg = tarjanAlg . asGraph 29 | 30 | 31 | tableGraph :: TableGraph 32 | tableGraph = [ (1, [2, 3]) 33 | , (2, []) 34 | , (3, [1, 2]) ] 35 | 36 | cycles = tarjanAlg (asGraph tableGraph) 37 | 38 | cycles' = adaptedTarjanAlg tableGraph 39 | -------------------------------------------------------------------------------- /Materials/Back to the Future - Tech Talks NSU/Adapter2.hs: -------------------------------------------------------------------------------- 1 | module Main where 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Materials/Back to the Future - Tech Talks NSU/Strategy.hs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Materials/Back to the Future - Tech Talks NSU/Strategy.hs -------------------------------------------------------------------------------- /Materials/Design and Architecture in FP/ExistentialAntipattern.hs: -------------------------------------------------------------------------------- 1 | 2 | module World.Plasma where 3 | 4 | data Plasma = Plasma { plasmaPlayer :: Player } 5 | 6 | 7 | module World.Karyon where 8 | 9 | data Karyon = Karyon { karyonPlayer :: Player 10 | , karyonEnergy :: Energy } 11 | 12 | 13 | 14 | class Active i where 15 | activate :: i -> Point -> World -> OperatedWorld -> OperatedWorld 16 | 17 | 18 | -- module World.Karyon: 19 | instance Active Karyon where 20 | activate = undefined 21 | 22 | 23 | -- module World.Plasma: 24 | instance Active Plasma where 25 | activate = undefined 26 | 27 | 28 | -- module GameLogic.Types: 29 | {-# LANGUAGE ExistentialQuantification #-} 30 | data ActiveItem = forall i. Active i => MkActiveItem i 31 | type World = M.Map Point ActiveItem 32 | 33 | instance Active ActiveItem where 34 | activate (MkActiveItem i) = activate i 35 | 36 | worldMapFromList :: [(Point, ActiveItem)] -> World 37 | worldMapFromList = M.fromList 38 | 39 | 40 | packItem :: Active i => i -> ActiveItem 41 | packItem = MkActiveItem 42 | 43 | packedKaryon = packItem (Karyon 1 100) 44 | packedPlasma = packItem (Plasma 1) 45 | 46 | world = M.fromList [ (Point 1 1 1, packedKaryon) 47 | , (Point 1 1 2, packedPlasma) ] 48 | 49 | stepWorld world = M.foldrWithKey f M.empty world 50 | where 51 | f point (MkActiveItem i) operatedWorld = activate i point world operatedWorld 52 | 53 | stepWorld = M.foldrWithKey activate M.empty 54 | 55 | -------------------------------------------------------------------------------- /Materials/Design and Architecture in FP/GoodDesign-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Materials/Design and Architecture in FP/GoodDesign-1.png -------------------------------------------------------------------------------- /Materials/Design and Architecture in FP/GoodDesign-2-Problem1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Materials/Design and Architecture in FP/GoodDesign-2-Problem1.png -------------------------------------------------------------------------------- /Materials/Design and Architecture in FP/GoodDesign-2-Problem2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Materials/Design and Architecture in FP/GoodDesign-2-Problem2.png -------------------------------------------------------------------------------- /Materials/Design and Architecture in FP/GoodDesign-2-Problem3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Materials/Design and Architecture in FP/GoodDesign-2-Problem3.png -------------------------------------------------------------------------------- /Materials/Design and Architecture in FP/GoodDesign-2-Problem4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Materials/Design and Architecture in FP/GoodDesign-2-Problem4.png -------------------------------------------------------------------------------- /Materials/Design and Architecture in FP/GoodDesign-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Materials/Design and Architecture in FP/GoodDesign-2.png -------------------------------------------------------------------------------- /Materials/Design and Architecture in FP/WorldCellAdt.hs: -------------------------------------------------------------------------------- 1 | module GameLogic.Types where 2 | import qualified Data.Map as M 3 | 4 | data Item = Karyon ... 5 | | Plasma ... 6 | | Mitochondrion ... 7 | | Stone ... 8 | 9 | type World = M.Map Point Item 10 | type OperatedWorld = World 11 | 12 | module GameLogic.Logic where 13 | import GameLogic.Types 14 | 15 | stepWorld :: World -> World 16 | apply :: World -> Item -> OperatedWorld -> OperatedWorld 17 | 18 | 19 | import GameLogic.Karyon as Karyon 20 | import GameLogic.Plasma as Plasma 21 | 22 | apply w (Karyon a b c) ow = Karyon.apply w (a, b, c) ow 23 | apply w (Plasma c d) ow = Plasma.apply w (c, d) ow 24 | apply w (Mitochondrion e f g) ow = Mitochondrion.apply w (e, f, g) ow 25 | ... 26 | 27 | getEnergy :: Item -> Int 28 | getEnergy (Karyon e b c) = e 29 | getEnergy (Mitochondrion e f g) = e 30 | getEnergy _ = error "getEnergy unsupported." 31 | 32 | 33 | main = do 34 | putStrLn "Ok." -------------------------------------------------------------------------------- /Materials/Game Development Materials.txt: -------------------------------------------------------------------------------- 1 | Netwire 2 | ------- 3 | 4 | Tetris: 5 | http://scrambledeggsontoast.github.io/2014/09/23/tetris-netwire/#fn:whynetwire 6 | 7 | Netwire-Pong: 8 | https://github.com/crockeo/netwire-pong 9 | 10 | Netwire-Tutorial: 11 | https://github.com/crockeo/netwire-tutorial 12 | 13 | Input combinators for Netwire: 14 | https://github.com/Mokosha/netwire-input 15 | https://github.com/Mokosha/netwire-input-glfw 16 | 17 | Full example of Netwire (ver. < 5.0) 18 | http://stackoverflow.com/questions/14787797/full-example-for-netwire 19 | 20 | Game engines 21 | ------------ 22 | 23 | Hickory: 24 | https://github.com/asivitz/Hickory 25 | 26 | LambdaHack: 27 | https://github.com/LambdaHack/LambdaHack 28 | 29 | Elerea 30 | ------ 31 | 32 | Writing a game in Haskell: 33 | http://www.youtube.com/watch?v=1MNTerD8IuI 34 | 35 | Games 36 | ----- 37 | 38 | 3D Snake: 39 | https://github.com/mikeplus64/plissken 40 | 41 | Varoius prototypes: 42 | https://github.com/mlesniak/game 43 | -------------------------------------------------------------------------------- /Materials/Haskell в реальном мире - Статья/Haskell в реальном мире.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Materials/Haskell в реальном мире - Статья/Haskell в реальном мире.txt -------------------------------------------------------------------------------- /Materials/Haskell в реальном мире - Статья/merger 0.13.hs: -------------------------------------------------------------------------------- 1 | import System (getArgs) 2 | import System.Directory (getDirectoryContents, getCurrentDirectory) 3 | import Char (isDigit) 4 | 5 | type Year = Int 6 | type Month = Int 7 | type DateRange = (Year, Month) 8 | 9 | defaultDateRange :: DateRange 10 | defaultDateRange = (2011, 4) 11 | 12 | readDateRange :: Read a => String -> Maybe a 13 | readDateRange str = case reads str of 14 | [(x, _)] -> Just x 15 | _ -> Nothing 16 | 17 | isFileForMerge :: String -> DateRange -> Bool 18 | isFileForMerge s (y, m) | (25 == length s) && (all isDigit (take 21 s)) = 19 | let 20 | ry = read ((take 4 . drop 5) s) 21 | rm = read ((take 2 . drop 9) s) 22 | in ry == y && rm == m 23 | isFileForMerge _ _ | otherwise = False 24 | 25 | isTxt :: String -> Bool 26 | isTxt s = (drop ((length s) - 3) s) == "txt" 27 | 28 | filesToMerge :: [String] -> DateRange -> [String] 29 | filesToMerge ss dr = filter (\x -> isTxt x && isFileForMerge x dr) ss 30 | 31 | 32 | main :: IO () 33 | main = do 34 | args <- getArgs 35 | curDir <- getCurrentDirectory 36 | dirContents <- getDirectoryContents curDir 37 | let maybeDateRange = case args of 38 | (a:b:_) -> readDateRange (unwords [a, b]) 39 | _ -> Just defaultDateRange 40 | case maybeDateRange of 41 | Just dr -> do 42 | fsToMerge = filesToMerge dirContents dr 43 | fsContents = merge fsToMerge 44 | putStrLn ("Files to merge: " ++ unlines fsToMerge) 45 | Nothing -> putStrLn ("Invalid date range.") -------------------------------------------------------------------------------- /Materials/Haskell в реальном мире - Статья/merger 0.14.hs: -------------------------------------------------------------------------------- 1 | import System (getArgs) 2 | import System.Directory (getDirectoryContents, getCurrentDirectory) 3 | import Char (isDigit) 4 | import Text.Printf (printf) 5 | import qualified Time as T 6 | 7 | type Year = Int 8 | type Month = Int 9 | type DateRange = (Year, Month) 10 | 11 | defaultDateRange :: T.CalendarTime -> DateRange 12 | defaultDateRange (T.CalendarTime y m _ _ _ _ _ _ _ _ _ _)= (y, fromEnum m + 1) 13 | 14 | readDateRange :: Read a => String -> Maybe a 15 | readDateRange str = case reads str of 16 | [(x, _)] -> Just x 17 | _ -> Nothing 18 | 19 | isFileForMerge :: String -> DateRange -> Bool 20 | isFileForMerge s (y, m) | (25 == length s) && (all isDigit (take 21 s)) = 21 | let 22 | ry = read ((take 4 . drop 5) s) 23 | rm = read ((take 2 . drop 9) s) 24 | in ry == y && rm == m 25 | isFileForMerge _ _ | otherwise = False 26 | 27 | isTxt :: String -> Bool 28 | isTxt s = (drop ((length s) - 3) s) == "txt" 29 | 30 | filesToMerge :: [String] -> DateRange -> [String] 31 | filesToMerge ss dr = filter (\x -> isTxt x && isFileForMerge x dr) ss 32 | 33 | merge :: [String] -> IO [String] 34 | merge fsToMerge = mapM readFile fsToMerge 35 | 36 | newFileName :: DateRange -> String 37 | newFileName (y, m) = printf "%s.%02s.txt" (show y) (show m) 38 | 39 | main :: IO () 40 | main = do 41 | args <- getArgs 42 | curDir <- getCurrentDirectory 43 | dirContents <- getDirectoryContents curDir 44 | curTime <- T.getClockTime 45 | monthAgoTime <- return $ T.addToClockTime (T.TimeDiff 0 (-1) 0 0 0 0 0) curTime 46 | calendarMonthAgoTime <- T.toCalendarTime monthAgoTime 47 | let maybeDateRange = case args of 48 | (a:b:_) -> readDateRange (unwords [a, b]) 49 | _ -> Just $ defaultDateRange calendarMonthAgoTime 50 | case maybeDateRange of 51 | Just dr -> do 52 | let fsToMerge = filesToMerge dirContents dr 53 | let fsToMergeCountStr = show $ length fsToMerge 54 | let mergeLog = (newFileName dr ++ ".log") 55 | let dateRangeMsg = "DateRange: " ++ show dr 56 | fsContents <- merge fsToMerge 57 | writeFile (newFileName dr) (unlines fsContents) 58 | writeFile mergeLog (unlines fsToMerge ++ printf "\n%s\nTotal files: %s" dateRangeMsg fsToMergeCountStr) 59 | putStrLn (unlines fsContents) 60 | putStrLn dateRangeMsg 61 | --putStrLn ("Files to merge: " ++ unlines fsToMerge) 62 | putStrLn (printf "Count of files: %s. See %s for file list." fsToMergeCountStr mergeLog) 63 | Nothing -> putStrLn ("Invalid date range.") -------------------------------------------------------------------------------- /Materials/Haskell в реальном мире - Статья/merger 0.16.hs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Materials/Haskell в реальном мире - Статья/merger 0.16.hs -------------------------------------------------------------------------------- /Materials/Haskell в реальном мире - Статья/merger 0.23.hs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Materials/Haskell в реальном мире - Статья/merger 0.23.hs -------------------------------------------------------------------------------- /Materials/Haskell в реальном мире - Статья/parser 0.12.hs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Materials/Haskell в реальном мире - Статья/parser 0.12.hs -------------------------------------------------------------------------------- /Materials/Haskell в реальном мире - Статья/parser 0.2.hs: -------------------------------------------------------------------------------- 1 | import Data.List 2 | 3 | replaceChars :: Char -> Char -> Char -> Char 4 | replaceChars whatC withC c = if c == whatC then withC else c 5 | 6 | interestFields :: [String] -> [Int] -> [String] 7 | interestFields s takeWhat = undefined 8 | 9 | isR200 :: [String] -> Bool 10 | isR200 s = (head s) == "R200" 11 | 12 | processLine :: String -> String 13 | processLine s = if isR200 sInWords then unwords (interestFields sInWords [1,2,3] ) else [] 14 | where sInWords = words ( map (replaceChars '|' ' ') s ) 15 | 16 | processString :: String -> [String] 17 | processString s = map processLine (lines $ s) 18 | 19 | main :: IO () 20 | main = do 21 | str <- readFile "merged.txt" 22 | putStrLn (intercalate "\r\n" (processString $ str)) 23 | -------------------------------------------------------------------------------- /Materials/Haskell в реальном мире - Статья/parser 0.6.hs: -------------------------------------------------------------------------------- 1 | import Data.List isR200 :: [String] -> Bool isR200 s = (head s) == "R200" replaceChar :: Char -> Char -> Char -> Char replaceChar whatC withC c = if c == whatC then withC else c replaceSymbols :: String -> String replaceSymbols s = map (replaceChar '|' ' ') (map (replaceChar ' ' '*') s) takeInterest :: [String] -> [Int] -> [String] takeInterest _ [] = [] takeInterest ss (n:ns) = [ss !! n] ++ takeInterest ss ns interestFields :: [String] -> [Int] -> [String] interestFields ss takeWhat | (maximum takeWhat) < length ss = takeInterest ss takeWhat | otherwise = undefined makeNewLine :: [String] -> String makeNewLine str = map (replaceChar ' ' '|') (unwords (interestFields str [7,8,9])) processLine :: String -> String processLine s = if isR200 sInWords then map (replaceChar '*' ' ') (makeNewLine sInWords) else [] where sInWords = words . replaceSymbols $ s processString :: String -> [String] processString s = {-take 10-} (filter (\a -> a /= []) (map processLine (lines $ s))) main :: IO () main = do str <- readFile "merged.txt" let processedStr = intercalate "\n" (processString $ str) putStrLn processedStr writeFile "processed.txt" processedStr -------------------------------------------------------------------------------- /Materials/YAMT/Mike Vanier's monad tutorial part 1 - Translation.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Materials/YAMT/Mike Vanier's monad tutorial part 1 - Translation.txt -------------------------------------------------------------------------------- /Materials/YAMT/Mike Vanier's monad tutorial part 2 - Translation.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Materials/YAMT/Mike Vanier's monad tutorial part 2 - Translation.txt -------------------------------------------------------------------------------- /Materials/YAMT/Mike Vanier's monad tutorial part 3 - Translation.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Materials/YAMT/Mike Vanier's monad tutorial part 3 - Translation.txt -------------------------------------------------------------------------------- /Materials/YAMT/Mike Vanier's monad tutorial part 4 - Translation.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Materials/YAMT/Mike Vanier's monad tutorial part 4 - Translation.txt -------------------------------------------------------------------------------- /Materials/YAMT/Mike Vanier's monad tutorial part 5 - Translation.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Materials/YAMT/Mike Vanier's monad tutorial part 5 - Translation.txt -------------------------------------------------------------------------------- /Programs/GameOfLifeComonad/.gitignore: -------------------------------------------------------------------------------- 1 | *.hi 2 | *.o 3 | .buildDir 4 | .dist-buildwrapper 5 | .bin 6 | dist 7 | .project~ 8 | *~ 9 | .tree 10 | .swp 11 | ./GlossMetaLife 12 | .exe -------------------------------------------------------------------------------- /Programs/GameOfLifeComonad/Life.hs: -------------------------------------------------------------------------------- 1 | {- 2 | This code taken from Habrahabr: 3 | http://habrahabr.ru/post/225473/ 4 | -} 5 | 6 | module Life where 7 | 8 | import Control.Comonad 9 | import Control.Applicative 10 | 11 | import Universe 12 | 13 | data Cell = Dead | Alive 14 | deriving (Eq, Show) 15 | 16 | nearest3 :: Universe a -> [a] 17 | nearest3 u = fmap extract [left u, u, right u] 18 | 19 | neighbours :: (Universe2 a) -> [a] 20 | neighbours u = 21 | [ nearest3 . extract . left 22 | , pure . extract . left . extract 23 | , pure . extract . right . extract 24 | , nearest3 . extract . right 25 | ] >>= ($ getUniverse2 u) 26 | 27 | rule :: Universe2 Cell -> Cell 28 | rule u 29 | | nc == 2 = extract u 30 | | nc == 3 = Alive 31 | | otherwise = Dead 32 | where nc = length $ filter (==Alive) (neighbours u) 33 | 34 | fromList :: a -> [a] -> Universe a 35 | fromList d (x:xs) = Universe (repeat d) x (xs ++ repeat d) 36 | 37 | fromList2 :: a -> [[a]] -> Universe2 a 38 | fromList2 d = Universe2 . fromList ud . fmap (fromList d) 39 | where ud = Universe (repeat d) d (repeat d) 40 | 41 | cells = [ [ Dead, Alive, Dead] 42 | , [Alive, Dead, Dead] 43 | , [Alive, Alive, Alive] ] 44 | 45 | initialModel :: Universe2 Cell 46 | initialModel = fromList2 Dead cells 47 | 48 | stepLifeUniverse = (=>> rule) 49 | -------------------------------------------------------------------------------- /Programs/GameOfLifeComonad/SampleCells.hs: -------------------------------------------------------------------------------- 1 | module SampleCells where 2 | 3 | import MetaLife 4 | 5 | metaCells = map (map zeroCellCreator) cellsGlider 6 | 7 | cells' = [[alive, alive, dead, alive, alive]] 8 | 9 | cells'' = [[alive, alive, alive]] 10 | 11 | cellsGlider = [ [ dead, alive, dead] 12 | , [alive, dead, dead] 13 | , [alive, alive, alive] ] 14 | 15 | cells''' = [ [dead, dead, dead, dead, alive, dead ] 16 | , [dead, dead, dead, alive, dead, dead ] 17 | , [dead, dead, dead, alive, alive, alive ] 18 | , [dead, dead, dead, dead, dead, dead ] 19 | , [dead, dead, dead, dead, dead, dead ] 20 | , [dead, dead, dead, dead, dead, dead ] 21 | , [dead, dead, dead, dead, dead, dead ] 22 | , [dead, dead, dead, dead, dead, dead ] 23 | , [alive, dead, alive, alive, alive, alive ] 24 | , [dead, alive, alive, alive, dead, alive ] 25 | , [alive, dead, dead, alive, alive, alive ] 26 | , [dead, alive, dead, dead, alive, dead ] 27 | , [alive, dead, dead, alive, alive, dead ] 28 | , [dead, alive, alive, dead, dead, alive ] 29 | , [alive, dead, alive, alive, alive, alive ] 30 | , [dead, alive, alive, dead, alive, alive ] 31 | , [alive, dead, alive, dead, alive, alive ] 32 | , [dead, alive, dead, dead, alive, dead ] 33 | , [alive, dead, alive, alive, dead, dead ] 34 | , [dead, alive, alive, dead, alive, alive ] 35 | , [alive, dead, dead, alive, dead, dead ] 36 | ] 37 | 38 | testLine = [ alive : replicate 28 dead ++ [alive]] 39 | testBlock = [ replicate 14 dead ++ [alive, alive] ++ replicate 14 dead] 40 | fillers n = replicate n (replicate 30 dead) 41 | 42 | testCells = testLine 43 | ++ fillers 6 44 | ++ testLine 45 | ++ fillers 6 46 | ++ testBlock 47 | ++ testBlock 48 | ++ fillers 6 49 | ++ testLine 50 | ++ fillers 6 51 | ++ testLine 52 | -------------------------------------------------------------------------------- /Programs/GameOfLifeComonad/Universe.hs: -------------------------------------------------------------------------------- 1 | {- 2 | This code taken from Habrahabr: 3 | http://habrahabr.ru/post/225473/ 4 | -} 5 | module Universe where 6 | 7 | import Control.Comonad 8 | import qualified Data.Vector as V 9 | 10 | type Current = Int 11 | data Universe a = Universe (V.Vector a) Int 12 | newtype Universe2 a = Universe2 { getUniverse2 :: Universe (Universe a) } 13 | 14 | left :: Universe a -> Universe a 15 | left (Universe v 0) = Universe v (V.length v - 1) 16 | left (Universe v cur) = Universe v (cur - 1) 17 | 18 | right :: Universe a -> Universe a 19 | right (Universe v cur) | cur == (V.length v - 1) = Universe v 0 20 | | otherwise = Universe v (cur + 1) 21 | 22 | left2 = left . left 23 | left3 = left . left . left 24 | 25 | right2 = right . right 26 | right3 = right . right . right 27 | 28 | makeUniverse fl fr x@(Universe v cur) = newUniverse 29 | where 30 | s = V.length v 31 | lvs = if cur == 0 then [] else take cur . tail $ iterate fl x 32 | rvs = if cur == s - 1 then [] else take (s - cur - 1) . tail $ iterate fr x 33 | vs = lvs ++ [x] ++ rvs 34 | newUniverse = Universe (V.fromList vs) cur 35 | 36 | instance Functor Universe where 37 | fmap f (Universe v cur) = Universe (V.map f v) cur 38 | 39 | instance Comonad Universe where 40 | duplicate = makeUniverse left right 41 | extract (Universe v cur) = V.unsafeIndex v cur 42 | 43 | takeRange :: (Int, Int) -> Universe a -> [a] 44 | takeRange (a, b) (Universe v _) | a < 0 = V.toList $ V.slice (1 - a) (b - a + 1) v 45 | takeRange (a, b) (Universe v _) | a >= 0 = V.toList $ V.slice (a - 1) (b - a + 1) v 46 | 47 | instance Functor Universe2 where 48 | fmap f = Universe2 . (fmap . fmap) f . getUniverse2 49 | 50 | instance Comonad Universe2 where 51 | extract = extract . extract . getUniverse2 52 | duplicate = fmap Universe2 . Universe2 . shifted . shifted . getUniverse2 53 | where shifted :: Universe (Universe a) -> Universe (Universe (Universe a)) 54 | shifted = makeUniverse (fmap left) (fmap right) 55 | 56 | nearest3 :: Universe a -> [a] 57 | nearest3 u = fmap extract [left u, u, right u] 58 | 59 | nearest5 :: Universe a -> [a] 60 | nearest5 u = fmap extract [left2 u, right2 u] ++ nearest3 u 61 | 62 | nearest7 :: Universe a -> [a] 63 | nearest7 u = fmap extract [left3 u, right3 u] ++ nearest5 u 64 | 65 | fromListU :: Int -> a -> [a] -> Universe a 66 | fromListU _ _ [] = error "Empty list." 67 | fromListU 0 _ _ = error "Invalid size." 68 | fromListU s zeroC xs | length xs > s = error "Invalid bounds." 69 | | otherwise = 70 | let unfilled = s - (length xs) 71 | unfR = unfilled `div` 2 72 | unfL = unfilled - unfR 73 | rsL = replicate unfL zeroC 74 | rsR = replicate unfR zeroC 75 | xs' = rsL ++ xs ++ rsR 76 | in Universe (V.fromList xs') 0 77 | 78 | fromList2 :: Int -> a -> [[a]] -> Universe2 a 79 | fromList2 s zeroC xss = Universe2 vss 80 | where 81 | zeroU = fromListU s zeroC . replicate s $ zeroC 82 | vs = map (fromListU s zeroC) xss 83 | vss = fromListU s zeroU vs 84 | 85 | toList2 :: Universe2 a -> [[a]] 86 | toList2 u = vs 87 | where 88 | (Universe vu' _) = getUniverse2 u 89 | getCells (Universe v _) = V.toList v 90 | vs = map getCells (V.toList vu') 91 | -------------------------------------------------------------------------------- /Programs/GameOfLifeComonad/config.txt: -------------------------------------------------------------------------------- 1 | # This is GlossMetaMetaLife config file. 2 | # Format: 3 | # f1 f2 f3 f4 f5 ra1 ra2 ra3 fieldSize totalIters itersPerSec mode 4 | # mode = Play | Simulate 5 | # ra1, ra2, ra3 - Rule Area for bottom, middle and top rule levels respectively, 6 | # where the bottom level is the level of real game of life. 7 | # Rule area defines the area where the alive cells counting. 8 | # RuleArea = Ring1 -- Classic ring of neighbour cells with the radius == 3. 9 | # | Ring2 -- Next ring with the radius == 5. 10 | # | Ring3 -- Next ring with the radius == 7. 11 | # The first conf is counting. 12 | # 13 | 14 | 2 1 0 0 0 Ring1 Ring2 Ring3 60 1000 4 Simulate 15 | 16 | 17 | 1 2 1 0 0 Ring1 Ring2 Ring3 60 1000 4 Simulate 18 | 0 0 0 1 1 Ring1 Ring2 Ring3 60 1000 4 Simulate 19 | 20 | -------------------------------------------------------------------------------- /Programs/GameOfLifeComonad/run.cmd: -------------------------------------------------------------------------------- 1 | ghc -O2 -threaded -rtsopts GlossMetaLife.hs 2 | .\GlossMetaLife +RTS -N8 -RTS 3 | -------------------------------------------------------------------------------- /Programs/GameOfLifeComonad/run.sh: -------------------------------------------------------------------------------- 1 | rm *.hi *.o GlossMetaLife 2 | ghc -O2 -threaded -rtsopts GlossMetaLife.hs 3 | ./GlossMetaLife +RTS -N8 -RTS 4 | -------------------------------------------------------------------------------- /Programs/HabrFormat/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *.exe 3 | *.o 4 | *.hi -------------------------------------------------------------------------------- /Programs/HabrFormat/article.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Programs/HabrFormat/article.html -------------------------------------------------------------------------------- /Programs/HabrFormat/formated_article.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Programs/HabrFormat/formated_article.html -------------------------------------------------------------------------------- /Programs/NgnTraffic Old/LicenseTemplate.txt: -------------------------------------------------------------------------------- 1 | {- 2 | /**************************************************************************** 3 | ** NgnTrafficParser 1.0 4 | ** Copyright (C) 2011 Granin A.S. 5 | ** Contact: Granin A.S. (graninas@gmail.com) 6 | ** 7 | ** This file is part of NgnTrafficParser 1.0. 8 | ** 9 | ** GNU General Public License Usage 10 | ** This file may be used under the terms of the GNU 11 | ** General Public License version 3.0 as published by the Free Software 12 | ** Foundation and appearing in the file LICENSE.GPL3 included in the 13 | ** packaging of this file. Please review the following information to 14 | ** ensure the GNU General Public License version 3.0 requirements will be 15 | ** met: http://www.gnu.org/licenses/gpl.html. 16 | ** 17 | ** If you have questions regarding the use of this file, please contact 18 | ** author (graninas@gmail.com). 19 | ** 20 | ****************************************************************************/ 21 | -} -------------------------------------------------------------------------------- /Programs/NgnTraffic Old/merger.hs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Programs/NgnTraffic Old/merger.hs -------------------------------------------------------------------------------- /Programs/NgnTraffic Old/parser.hs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Programs/NgnTraffic Old/parser.hs -------------------------------------------------------------------------------- /Programs/NgnTraffic/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *.hi 3 | *.exe 4 | *.o -------------------------------------------------------------------------------- /Programs/NgnTraffic/Constants.hs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Programs/NgnTraffic/Constants.hs -------------------------------------------------------------------------------- /Programs/NgnTraffic/DataProcess.hs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Programs/NgnTraffic/DataProcess.hs -------------------------------------------------------------------------------- /Programs/NgnTraffic/FileListProcess.hs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Programs/NgnTraffic/FileListProcess.hs -------------------------------------------------------------------------------- /Programs/NgnTraffic/LicenseTemplate.txt: -------------------------------------------------------------------------------- 1 | {- 2 | /**************************************************************************** 3 | ** NgnTrafficParser 2.0 4 | ** Copyright (C) 2011 Granin A.S. 5 | ** Contact: Granin A.S. (graninas@gmail.com) 6 | ** 7 | ** This file is part of NgnTrafficParser 2.0. 8 | ** 9 | ** GNU General Public License Usage 10 | ** This file may be used under the terms of the GNU 11 | ** General Public License version 3.0 as published by the Free Software 12 | ** Foundation and appearing in the file LICENSE.GPL3 included in the 13 | ** packaging of this file. Please review the following information to 14 | ** ensure the GNU General Public License version 3.0 requirements will be 15 | ** met: http://www.gnu.org/licenses/gpl.html. 16 | ** 17 | ** If you have questions regarding the use of this file, please contact 18 | ** author (graninas@gmail.com). 19 | ** 20 | ****************************************************************************/ 21 | -} -------------------------------------------------------------------------------- /Programs/NgnTraffic/NgnTraffic.hs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Programs/NgnTraffic/NgnTraffic.hs -------------------------------------------------------------------------------- /Programs/NgnTraffic/Options.hs: -------------------------------------------------------------------------------- 1 | {- 2 | /**************************************************************************** 3 | ** NgnTrafficParser 2.0 4 | ** Copyright (C) 2011 Granin A.S. 5 | ** Contact: Granin A.S. (graninas@gmail.com) 6 | ** 7 | ** This file is part of NgnTrafficParser 2.0. 8 | ** 9 | ** GNU General Public License Usage 10 | ** This file may be used under the terms of the GNU 11 | ** General Public License version 3.0 as published by the Free Software 12 | ** Foundation and appearing in the file LICENSE.GPL3 included in the 13 | ** packaging of this file. Please review the following information to 14 | ** ensure the GNU General Public License version 3.0 requirements will be 15 | ** met: http://www.gnu.org/licenses/gpl.html. 16 | ** 17 | ** If you have questions regarding the use of this file, please contact 18 | ** author (graninas@gmail.com). 19 | ** 20 | ****************************************************************************/ 21 | -} 22 | 23 | module Options where 24 | 25 | import Types 26 | import qualified Data.List as L ((\\)) 27 | 28 | optionsFromArgs :: [String] -> Options 29 | optionsFromArgs [] = [] 30 | optionsFromArgs ("-f":fs) = case (reads . unwords) fs of 31 | [(idxList, rest)] -> (FieldsToCollect idxList) : ( (optionsFromArgs . words) rest) 32 | _ -> optionsFromArgs fs 33 | 34 | optionsFromArgs ("-ym":fs) = case (reads . unwords) fs of 35 | [(ym, rest)] -> (TargetYearMonth ym) : ( (optionsFromArgs . words) rest) 36 | _ -> optionsFromArgs fs 37 | 38 | optionsFromArgs ("-w":fs) = WaitAfterDone : optionsFromArgs fs 39 | optionsFromArgs (arg:args) = optionsFromArgs args 40 | 41 | defaultOptions :: FieldIndexes -> YearMonth -> Options 42 | defaultOptions fis ym = [FieldsToCollect fis, TargetYearMonth ym] 43 | 44 | compileOptions :: Options -> Options -> Options 45 | compileOptions opts defOpts = opts ++ (defOpts L.\\ opts) 46 | 47 | getYearMonth :: Options -> YearMonth 48 | getYearMonth [] = undefined 49 | getYearMonth ((TargetYearMonth x):_) = x 50 | getYearMonth (_:os) = getYearMonth os 51 | 52 | getFieldIndexes :: Options -> FieldIndexes 53 | getFieldIndexes [] = undefined 54 | getFieldIndexes ((FieldsToCollect x):_) = x 55 | getFieldIndexes (_:os) = getFieldIndexes os 56 | 57 | getWait :: Options -> Bool 58 | getWait = not . null . filter (== WaitAfterDone) -------------------------------------------------------------------------------- /Programs/NgnTraffic/README: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Programs/NgnTraffic/README -------------------------------------------------------------------------------- /Programs/NgnTraffic/Tools.hs: -------------------------------------------------------------------------------- 1 | {- 2 | /**************************************************************************** 3 | ** NgnTrafficParser 2.0 4 | ** Copyright (C) 2011 Granin A.S. 5 | ** Contact: Granin A.S. (graninas@gmail.com) 6 | ** 7 | ** This file is part of NgnTrafficParser 2.0. 8 | ** 9 | ** GNU General Public License Usage 10 | ** This file may be used under the terms of the GNU 11 | ** General Public License version 3.0 as published by the Free Software 12 | ** Foundation and appearing in the file LICENSE.GPL3 included in the 13 | ** packaging of this file. Please review the following information to 14 | ** ensure the GNU General Public License version 3.0 requirements will be 15 | ** met: http://www.gnu.org/licenses/gpl.html. 16 | ** 17 | ** If you have questions regarding the use of this file, please contact 18 | ** author (graninas@gmail.com). 19 | ** 20 | ****************************************************************************/ 21 | -} 22 | 23 | module Tools where 24 | 25 | import qualified System.Time as T (TimeDiff(..), CalendarTime(..), ClockTime(..), addToClockTime, toClockTime) 26 | import Data.Char (toUpper, toLower) 27 | import Types 28 | 29 | firstMonthDay :: T.CalendarTime -> T.CalendarTime 30 | firstMonthDay ct = ct {T.ctDay = 1} 31 | 32 | prevMonthBegin :: T.CalendarTime -> T.ClockTime 33 | prevMonthBegin curMonth = T.addToClockTime (T.TimeDiff 0 (-1) 0 0 0 0 0) (T.toClockTime $ firstMonthDay curMonth) 34 | 35 | toYearMonth :: T.CalendarTime -> YearMonth 36 | toYearMonth (T.CalendarTime y m _ _ _ _ _ _ _ _ _ _)= (y, fromEnum m + 1) 37 | 38 | capitalize :: String -> String 39 | capitalize [] = [] 40 | capitalize (l:ls) = toUpper l : map toLower ls 41 | 42 | -------------------------------------------------------------------------------- /Programs/NgnTraffic/Types.hs: -------------------------------------------------------------------------------- 1 | {- 2 | /**************************************************************************** 3 | ** NgnTrafficParser 2.0 4 | ** Copyright (C) 2011 Granin A.S. 5 | ** Contact: Granin A.S. (graninas@gmail.com) 6 | ** 7 | ** This file is part of NgnTrafficParser 2.0. 8 | ** 9 | ** GNU General Public License Usage 10 | ** This file may be used under the terms of the GNU 11 | ** General Public License version 3.0 as published by the Free Software 12 | ** Foundation and appearing in the file LICENSE.GPL3 included in the 13 | ** packaging of this file. Please review the following information to 14 | ** ensure the GNU General Public License version 3.0 requirements will be 15 | ** met: http://www.gnu.org/licenses/gpl.html. 16 | ** 17 | ** If you have questions regarding the use of this file, please contact 18 | ** author (graninas@gmail.com). 19 | ** 20 | ****************************************************************************/ 21 | -} 22 | 23 | module Types where 24 | 25 | import qualified Data.ByteString.Char8 as C 26 | 27 | type Year = Int 28 | type Month = Int 29 | type YearMonth = (Year, Month) 30 | 31 | type ResFilePath = FilePath 32 | 33 | type FieldIndex = Int 34 | type FieldIndexes = [FieldIndex] 35 | type FieldDelimiter = Char 36 | type Fields = [C.ByteString] 37 | 38 | data Predicate = NotInList [C.ByteString] 39 | | InList [C.ByteString] 40 | | Like [C.ByteString] 41 | | LengthLess Int 42 | type PredicateMap = [(FieldIndex, Predicate)] 43 | 44 | 45 | data Option = FieldsToCollect FieldIndexes 46 | | TargetYearMonth YearMonth 47 | | WaitAfterDone 48 | deriving (Show, Read) 49 | 50 | type Options = [Option] 51 | 52 | instance Eq Option where 53 | (FieldsToCollect x) == (FieldsToCollect y) = True 54 | (TargetYearMonth x) == (TargetYearMonth y) = True 55 | (WaitAfterDone) == (WaitAfterDone) = True 56 | a == b = False 57 | -------------------------------------------------------------------------------- /Programs/RestCorrecting/LicenseTemplate.txt: -------------------------------------------------------------------------------- 1 | {- 2 | /**************************************************************************** 3 | ** RestCorrecting 1.0 4 | ** Copyright (C) 2011 Granin A.S. 5 | ** Contact: Granin A.S. (graninas@gmail.com) 6 | ** 7 | ** This file is part of RestCorrecting 1.0. 8 | ** 9 | ** GNU General Public License Usage 10 | ** This file may be used under the terms of the GNU 11 | ** General Public License version 3.0 as published by the Free Software 12 | ** Foundation and appearing in the file LICENSE.GPL3 included in the 13 | ** packaging of this file. Please review the following information to 14 | ** ensure the GNU General Public License version 3.0 requirements will be 15 | ** met: http://www.gnu.org/licenses/gpl.html. 16 | ** 17 | ** If you have questions regarding the use of this file, please contact 18 | ** author (graninas@gmail.com). 19 | ** 20 | ****************************************************************************/ 21 | -} -------------------------------------------------------------------------------- /Programs/RestCorrecting/README: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Programs/RestCorrecting/README -------------------------------------------------------------------------------- /Programs/RestCorrecting/Sql.hs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Programs/RestCorrecting/Sql.hs -------------------------------------------------------------------------------- /Programs/RestCorrecting/TestData.hs: -------------------------------------------------------------------------------- 1 | {- 2 | /**************************************************************************** 3 | ** RestCorrecting 1.0 4 | ** Copyright (C) 2011 Granin A.S. 5 | ** Contact: Granin A.S. (graninas@gmail.com) 6 | ** 7 | ** This file is part of RestCorrecting 1.0. 8 | ** 9 | ** GNU General Public License Usage 10 | ** This file may be used under the terms of the GNU 11 | ** General Public License version 3.0 as published by the Free Software 12 | ** Foundation and appearing in the file LICENSE.GPL3 included in the 13 | ** packaging of this file. Please review the following information to 14 | ** ensure the GNU General Public License version 3.0 requirements will be 15 | ** met: http://www.gnu.org/licenses/gpl.html. 16 | ** 17 | ** If you have questions regarding the use of this file, please contact 18 | ** author (graninas@gmail.com). 19 | ** 20 | ****************************************************************************/ 21 | -} 22 | 23 | module TestData where 24 | 25 | 26 | import Types 27 | 28 | testDataCharges :: Charges 29 | testDataCharges = [ 30 | (882513, 83, 146 , 0 ), 31 | (888914, 86, 20.14 , 0 ), 32 | (901151, 83, 146 , 0 ), 33 | (910652, 83, 160 , 0 ), 34 | (923097, 86, 25.2 , 0 ), 35 | (925555, 97, 4.5 , 0 ), 36 | (933432, 86, 24.84 , 0 ), 37 | (942629, 83, 160 , 0 ), 38 | (953871, 86, 25.56 , 0 ), 39 | (961474, 83, 160 , 0 ), 40 | (970190, 86, 6.12 , 0 ), 41 | (980051, 83, 160 , 0 ), 42 | (989861, 86, 8.64 , 0 ), 43 | (999726, 83, 160 , 0 ), 44 | (1007970, 86, 5.4 , 0 ), 45 | (1016764, 83, 160 , 0 ), 46 | (1025142, 93, 6 , 0 ), 47 | (1028077, 86, 6.48 , 0.0 ), 48 | (1034160, 83, 160 , 160 ), 49 | (1045654, 86, 9.36 , 9.36 ), 50 | (1051899, 83, 160 , 0 ), 51 | (1063557, 86, 18.36 , 0 ), 52 | (1065272, 83, (-252.9) , (-200) ) 53 | ] 54 | 55 | testDataPayments :: Payments 56 | testDataPayments = [ 57 | (408703, 0, 113.88 , 0 ), 58 | (417630, 0, 180 , 0 ), 59 | (425139, 0, 193 , 0 ), 60 | (431755, 0, 185 , 0 ), 61 | (439355, 0, 185 , 0 ), 62 | (446878, 0, 200 , 0 ), 63 | (461092, 0, 300 , 52.88 ), 64 | (468648, 0, 180 , 150 ), 65 | (475296, 0, 170 , 160 ) 66 | ] -------------------------------------------------------------------------------- /Programs/RestCorrecting/Types.hs: -------------------------------------------------------------------------------- 1 | {- 2 | /**************************************************************************** 3 | ** RestCorrecting 1.0 4 | ** Copyright (C) 2011 Granin A.S. 5 | ** Contact: Granin A.S. (graninas@gmail.com) 6 | ** 7 | ** This file is part of RestCorrecting 1.0. 8 | ** 9 | ** GNU General Public License Usage 10 | ** This file may be used under the terms of the GNU 11 | ** General Public License version 3.0 as published by the Free Software 12 | ** Foundation and appearing in the file LICENSE.GPL3 included in the 13 | ** packaging of this file. Please review the following information to 14 | ** ensure the GNU General Public License version 3.0 requirements will be 15 | ** met: http://www.gnu.org/licenses/gpl.html. 16 | ** 17 | ** If you have questions regarding the use of this file, please contact 18 | ** author (graninas@gmail.com). 19 | ** 20 | ****************************************************************************/ 21 | -} 22 | 23 | module Types where 24 | 25 | 26 | data RawValue = DoubleVal Double 27 | | Int32Val Int 28 | -- | Int64Val Int 29 | deriving (Show) 30 | 31 | type RawRow = [RawValue] 32 | type RawData = [RawRow] 33 | 34 | -- (ID_RECORD, ID_USL, SUMMA, OST_REC) 35 | type Record = (Int, Int, Double, Double) 36 | type Records = [Record] 37 | 38 | type Charge = Record 39 | type Charges = Records 40 | 41 | type Payment = Record 42 | type Payments = Records 43 | 44 | -------------------------------------------------------------------------------- /Programs/RestCorrecting/dbDataTest.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Programs/RestCorrecting/dbDataTest.txt -------------------------------------------------------------------------------- /Programs/RestCorrecting/id_obsh.txt: -------------------------------------------------------------------------------- 1 | 1294 2 | 1434 3 | 1510 4 | 1541 5 | 2005 6 | 2144 7 | 2261 8 | 2304 9 | 2447 10 | 2820 11 | 3622 12 | 3659 13 | 4023 14 | 4643 15 | 5138 16 | 5867 17 | 5870 18 | 6628 19 | 7191 20 | 7793 21 | 7833 22 | 7948 23 | 8001 24 | 8969 25 | 9202 26 | 9250 -------------------------------------------------------------------------------- /Programs/RestCorrecting/testResult.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Programs/RestCorrecting/testResult.txt -------------------------------------------------------------------------------- /Programs/RestCorrecting/updateScripts.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Programs/RestCorrecting/updateScripts.sql -------------------------------------------------------------------------------- /Programs/SimpleFormat/Process.hs: -------------------------------------------------------------------------------- 1 | module Process where 2 | 3 | import Data.List (isPrefixOf) 4 | 5 | type BorderElement = String 6 | type OpenTag = String 7 | type CloseTag = String 8 | 9 | process :: String -> BorderElement -> (OpenTag, CloseTag) -> Bool -> String 10 | process [] _ _ _ = [] 11 | process xs el tags@(openT, _) True | el `isPrefixOf` xs = openT ++ process (drop (length el) xs ) el tags False 12 | process xs el tags@(_, closeT) False | el `isPrefixOf` xs = closeT ++ process (drop (length el) xs ) el tags True 13 | process (x:xs) el tags b = x : process xs el tags b -------------------------------------------------------------------------------- /Programs/SimpleFormat/SimpleFormat.hs: -------------------------------------------------------------------------------- 1 | module Main where 2 | 3 | import Process 4 | 5 | italic = ["__", "", ""] 6 | blue = ["@@", "", ""] 7 | bold = ["**", "", ""] 8 | doubleBlockQuote = ["<>", "
"] 9 | 10 | formatters :: [[String]] 11 | formatters = [italic, blue, bold, doubleBlockQuote] 12 | 13 | format :: [String] -> String -> String 14 | format (border : openTag : closeTag : _) s = process s border (openTag, closeTag) True 15 | 16 | 17 | main :: IO () 18 | main = do 19 | fContents <- readFile "text.txt" 20 | 21 | let result = foldr format fContents formatters 22 | 23 | writeFile "p_text.txt" result 24 | writeFile "p_text.html" result 25 | putStrLn "Ok." -------------------------------------------------------------------------------- /Prototypes/Adv2Game/Types.hs: -------------------------------------------------------------------------------- 1 | module Types where 2 | 3 | import qualified Data.Map as M 4 | 5 | 6 | removeProperty = undefined 7 | 8 | (|>) :: a -> a -> [a] 9 | x |> y = x : [y] 10 | 11 | (~->) :: a -> b -> (a, b) 12 | x ~-> y = (x, y) 13 | 14 | infixl 0 |> 15 | infixl 1 ~-> 16 | 17 | get = undefined 18 | put = undefined 19 | 20 | setState :: Monad m => String -> m a 21 | setState = undefined 22 | 23 | delProp :: Monad m => String -> a -> m a 24 | delProp = undefined 25 | 26 | mapSubObjects = undefined 27 | enableProperty = undefined 28 | 29 | noP = undefined 30 | 31 | getProperty = undefined 32 | 33 | prop :: Monad m => a -> [(String, m a)] 34 | prop = \o -> case getProperty "lockable" o of 35 | "locked" -> "unlock" ~-> setState "unlocked" |> 36 | "break" ~-> do 37 | delProp "lockable" o 38 | mapSubObjects enableProperty o 39 | "unlocked" -> [] 40 | 41 | 42 | 43 | lockable = undefined 44 | locked = undefined 45 | openable = undefined 46 | closed = undefined 47 | 48 | data Object a = Object 49 | { 50 | properties :: a 51 | } 52 | 53 | myObject = Object {properties = [lockable locked, openable closed]} 54 | -------------------------------------------------------------------------------- /Prototypes/Adv2Game/Types2.hs: -------------------------------------------------------------------------------- 1 | 2 | 3 | data Object = Object 4 | { 5 | properties :: [Property] 6 | } deriving (Eq) 7 | 8 | 9 | data Property = Property String [(State, String)] 10 | deriving (Eq) 11 | 12 | data State = State String 13 | deriving (Eq) 14 | 15 | switch (st1, act1) (st2, act2) x | x == st2 = [(st1, act1)] 16 | | x == st1 = [(st2, act2)] 17 | 18 | 19 | opened = State "opened" 20 | closed = State "closed" 21 | 22 | openable :: State -> Property 23 | openable = Property "openable" . switch (opened, "open") (closed, "close") 24 | 25 | drawer = Object { properties = [openable opened] } 26 | 27 | 28 | propertyActions :: Property -> [String] 29 | propertyActions (Property _ xs) = foldr (\(_, act) -> (act:)) [] xs 30 | 31 | actions :: [Property] -> [String] 32 | actions = foldr (\p -> (propertyActions p ++)) [] 33 | 34 | 35 | main :: IO () 36 | main = do 37 | putStrLn "test" 38 | -------------------------------------------------------------------------------- /Prototypes/BigSpace.EventFlowTree/Actions.hs: -------------------------------------------------------------------------------- 1 | module Actions where 2 | 3 | import Types 4 | import EventFlowTree 5 | import Event 6 | 7 | sendToFuture :: Int -> EventFlowTree -> Maybe EventFlowTree 8 | sendToFuture 0 tree = Nothing 9 | sendToFuture tick tree = Just $ update (tick, 'r', "SpaceShip sended to past and returned.") tree 10 | 11 | 12 | findEvent :: Char -> EventFlowTree -> Event 13 | findEvent ch tree = case lookupByEvent ch tree of 14 | Just e -> e 15 | Nothing -> emptyEvent -------------------------------------------------------------------------------- /Prototypes/BigSpace.EventFlowTree/Event.hs: -------------------------------------------------------------------------------- 1 | module Event where 2 | 3 | import Types 4 | 5 | emptyEvent :: Event 6 | emptyEvent = (0, '_', []) 7 | -------------------------------------------------------------------------------- /Prototypes/BigSpace.EventFlowTree/EventFlowTree.hs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Prototypes/BigSpace.EventFlowTree/EventFlowTree.hs -------------------------------------------------------------------------------- /Prototypes/BigSpace.EventFlowTree/Main.hs: -------------------------------------------------------------------------------- 1 | module Main where 2 | 3 | import Types 4 | import EventFlowTree 5 | import PreGen.World 6 | import Actions 7 | 8 | run :: Int -> EventFlowTree -> EventFlowTree -> IO () 9 | run tt preGenTree tree = do 10 | putStr (show tt ++ "tt ") 11 | act <- getLine 12 | case act of 13 | "send" -> let (t, _, _) = findEvent 'r' preGenTree in 14 | case sendToFuture t tree of 15 | Just newTree -> do 16 | putStrLn "SpaceShip sended to future." 17 | run (tt + 1) preGenTree newTree 18 | Nothing -> putStrLn "No send." >> run (tt + 1) preGenTree tree 19 | _ -> run (tt + 1) preGenTree tree 20 | 21 | 22 | 23 | 24 | main :: IO () 25 | main = do 26 | putStrLn "BigSpace" 27 | 28 | let gameSeconds = 31104000 29 | run 0 (fromTimeLine gameSeconds preGenWorldTL) $ mkEmptyTree gameSeconds -------------------------------------------------------------------------------- /Prototypes/BigSpace.EventFlowTree/PreGen/World.hs: -------------------------------------------------------------------------------- 1 | module PreGen.World where 2 | 3 | import Types 4 | 5 | preGenWorldTL :: TimeLine 6 | preGenWorldTL = 7 | (0, '_', "Time begin") 8 | : (10, '_', "SpaceShip from future!") 9 | : (15, '_', "SpaceShip was damaged.") 10 | : (20, '_', "SpaceShip sended back to the future.") 11 | : (100, 'S', "SpaceShip begin") 12 | : (zip3 [101..] "paceShip" $ repeat []) 13 | ++ ( 14 | (150, 'r', "SpaceShip sended to past and returned.") 15 | : (200, '_', "Time end") 16 | : [] 17 | ) -------------------------------------------------------------------------------- /Prototypes/BigSpace.EventFlowTree/README: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Prototypes/BigSpace.EventFlowTree/README -------------------------------------------------------------------------------- /Prototypes/BigSpace.EventFlowTree/Tools.hs: -------------------------------------------------------------------------------- 1 | module Tools where 2 | 3 | 4 | numberPowList :: Int -> [(Int, Int)] 5 | numberPowList n = zip [0..] $ scanl (*) 1 (repeat n) -------------------------------------------------------------------------------- /Prototypes/BigSpace.EventFlowTree/Types.hs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Prototypes/BigSpace.EventFlowTree/Types.hs -------------------------------------------------------------------------------- /Prototypes/BigSpace.EventFlowTree/test.txt: -------------------------------------------------------------------------------- 1 | Branch (0,3) 2 | (Branch (0,1) 3 | (Leaf (0,'_',"")) 4 | (Leaf (1,'_',""))) 5 | (Branch (2,3) 6 | (Leaf (2,'F',"SS!")) 7 | (Leaf (3,'_',""))) -------------------------------------------------------------------------------- /Prototypes/BigSpace.FingerTreeUnstructured/BigSpace.hs: -------------------------------------------------------------------------------- 1 | module Main where 2 | 3 | import Type.Types 4 | import Type.Event 5 | 6 | data WorldState a = WS 7 | { 8 | eventTree :: [Event a] 9 | } 10 | deriving (Show) 11 | 12 | zeroWorldState :: WorldState Int 13 | zeroWorldState = WS {eventTree = []} 14 | 15 | 16 | 17 | main = do 18 | 19 | x <- return zeroWorldState 20 | putStrLn "Done." -------------------------------------------------------------------------------- /Prototypes/BigSpace.FingerTreeUnstructured/Type/Constants.hs: -------------------------------------------------------------------------------- 1 | module Type.Constants where 2 | 3 | import qualified Data.Word as W 4 | 5 | type GeometryScale = W.Word32 6 | type TimeScale = W.Word32 7 | 8 | geometryLocalScale1Multiplier :: GeometryScale 9 | geometryLocalScale1Multiplier = 1000000 10 | 11 | geometryLocalScale2Multiplier :: GeometryScale 12 | geometryLocalScale2Multiplier = 1000 13 | -------------------------------------------------------------------------------- /Prototypes/BigSpace.FingerTreeUnstructured/Type/Event.hs: -------------------------------------------------------------------------------- 1 | module Type.Event where 2 | 3 | import Type.Types 4 | import Type.Universe 5 | 6 | import qualified Data.Foldable as F 7 | import qualified Data.Monoid as M 8 | 9 | data UniverseObject o => Event o = Event Position o 10 | deriving (Show) 11 | 12 | 13 | 14 | 15 | 16 | {- 17 | 18 | instance Functor (Entry k) where 19 | fmap f (Entry k v) = Entry k (f v) 20 | 21 | instance Foldable (Entry k) where 22 | foldMap f (Entry _ v) = f v 23 | 24 | instance Ord k => Monoid (Prio k v) where 25 | mempty = NoPrio 26 | x `mappend` NoPrio = x 27 | NoPrio `mappend` y = y 28 | x@(Prio kx _) `mappend` y@(Prio ky _) 29 | | kx <= ky = x 30 | | otherwise = y 31 | 32 | instance Ord k => Measured (Prio k v) (Entry k v) where 33 | measure (Entry k v) = Prio k v 34 | 35 | -} -------------------------------------------------------------------------------- /Prototypes/BigSpace.FingerTreeUnstructured/Type/EventTree.hs: -------------------------------------------------------------------------------- 1 | module Type.EventTree where 2 | 3 | import Types.Type 4 | import Types.Event 5 | 6 | import qualified Data.FingerTree as FT 7 | import qualified Data.Foldable (Foldable(foldMap)) as F 8 | 9 | type TopHistoryMeasure = (SpaceScale, SpaceTime) 10 | -------------------------------------------------------------------------------- /Prototypes/BigSpace.FingerTreeUnstructured/Type/Types.hs: -------------------------------------------------------------------------------- 1 | module Type.Types where 2 | 3 | import qualified Data.Word as W 4 | 5 | import Type.Constants 6 | 7 | data GeometryPosition = GP 8 | { 9 | gpLocal1Scale :: GeometryScale, 10 | gpLocal2Scale :: GeometryScale, 11 | gpPlanetaryScale :: GeometryScale, 12 | gpStarSystemScale :: GeometryScale 13 | } 14 | deriving (Show) 15 | 16 | data TimePosition = TP 17 | { 18 | tpLocalScale :: TimeScale, 19 | tpAgeScale :: TimeScale, 20 | tpEpochScale :: TimeScale 21 | } 22 | deriving (Show) 23 | 24 | data Position = Pos 25 | { 26 | pGeometryPosition :: GeometryPosition, 27 | pTimePosition :: TimePosition 28 | } 29 | deriving (Show) 30 | 31 | type SpaceScale = W.Word64 32 | type SpaceTime = W.Word64 33 | 34 | 35 | -------------------------------------------------------------------------------- /Prototypes/BigSpace.FingerTreeUnstructured/Type/Universe.hs: -------------------------------------------------------------------------------- 1 | module Type.Universe where 2 | 3 | import qualified Data.Word as W 4 | 5 | class UniverseObject o where 6 | objectId :: Word32 -------------------------------------------------------------------------------- /Setup.hs: -------------------------------------------------------------------------------- 1 | import Distribution.Simple 2 | main = defaultMain 3 | -------------------------------------------------------------------------------- /Tests/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *.exe 3 | *.hi 4 | *.o -------------------------------------------------------------------------------- /Tests/AppoxyHiringTask/Lucky.hs: -------------------------------------------------------------------------------- 1 | module Main where 2 | 3 | import Data.List as L 4 | 5 | withEqualConsequtives :: String -> Bool 6 | withEqualConsequtives s = any (\subS -> length subS > 1) . group $ s 7 | 8 | composeLucky :: String -> [String] 9 | composeLucky = L.nub . filter (not . withEqualConsequtives) . L.permutations 10 | 11 | howManyLuckies :: String -> Either String Int 12 | howManyLuckies s = if l >= 1 && l <= 10 13 | then Right $ length $ composeLucky s 14 | else Left "There are bounds: length should be in range [1,10]" 15 | where 16 | l = length s 17 | 18 | main = do 19 | s <- readFile "lucky.txt" 20 | print "Luckies count:" 21 | print $ howManyLuckies $ init s 22 | -------------------------------------------------------------------------------- /Tests/AppoxyHiringTask/StringOptimization.hs: -------------------------------------------------------------------------------- 1 | module Main where 2 | 3 | import Data.Maybe (fromJust) 4 | 5 | difference x y | length x == length y = Just $ difference' 0 x y 6 | | otherwise = Nothing 7 | where 8 | difference' d [] [] = d 9 | difference' d (x:xs) (y:ys) | x /= y = difference' (d + 1) xs ys 10 | | otherwise = difference' d xs ys 11 | 12 | 13 | findMinSubstringPos aLength minP curP dif [] _ = minP 14 | findMinSubstringPos aLength minP curP dif _ [] = minP 15 | findMinSubstringPos aLength minP curP dif a b@(_:bs) = case difference a (take aLength b) of 16 | Just d -> if d < dif 17 | then findMinSubstringPos aLength curP (curP + 1) d a bs 18 | else findMinSubstringPos aLength minP (curP + 1) dif a bs 19 | Nothing -> minP 20 | 21 | fillFromB minIdx a b = take (minIdx - 1) b 22 | ++ a 23 | ++ drop (minIdx - 1 + length a) b 24 | 25 | optimizeStrings a b | length a == length b = difference a b 26 | | otherwise = let 27 | aLength = length a 28 | minimumIndex = findMinSubstringPos aLength 1 1 (maxBound :: Int) a b 29 | minString = fillFromB minimumIndex a b 30 | in difference minString b 31 | 32 | minimize :: String -> String -> Either String Int 33 | minimize a b | length a > length b = Left "Length of A should be less or equal than length of B." 34 | | otherwise = Right $ fromJust $ optimizeStrings a b 35 | 36 | 37 | main = do 38 | a <- readFile "a.txt" 39 | b <- readFile "b.txt" 40 | putStrLn "Minimization difference:" 41 | print $ minimize a b 42 | -------------------------------------------------------------------------------- /Tests/AppoxyHiringTask/a.txt: -------------------------------------------------------------------------------- 1 | giorgi 2 | -------------------------------------------------------------------------------- /Tests/AppoxyHiringTask/b.txt: -------------------------------------------------------------------------------- 1 | igroig 2 | -------------------------------------------------------------------------------- /Tests/AppoxyHiringTask/lucky.txt: -------------------------------------------------------------------------------- 1 | abcdefghij 2 | -------------------------------------------------------------------------------- /Tests/ArrowsAndFrees/ArrEff.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE Arrows #-} 2 | module ArrEff where 3 | 4 | import Prelude hiding ((.), id) 5 | import Control.Category 6 | import Control.Arrow 7 | import Control.Monad.Free 8 | 9 | newtype ArrEff eff b c = ArrEff (b -> eff (c, ArrEff eff b c)) 10 | 11 | instance Monad eff => Category (ArrEff eff) where 12 | id = ArrEff (\b -> return (b, id)) 13 | ArrEff g . ArrEff f = ArrEff arrFG 14 | where 15 | arrFG a = do 16 | fa <- f a 17 | feededF fa 18 | feededF (b, arr1) = do 19 | gb <- g b 20 | feededG arr1 gb 21 | feededG arr1 (c, arr2) = return (c, arr2 . arr1) 22 | 23 | instance Monad eff => Arrow (ArrEff eff) where 24 | arr f = ArrEff (\b -> return (f b, arr f)) 25 | first (ArrEff f) = ArrEff arrF 26 | where 27 | arrF (b, d) = do 28 | fb <- f b 29 | feededF fb d 30 | feededF (c, arr1) d = return ((c, d), first arr1) 31 | 32 | instance Monad eff => Functor (ArrEff eff b) where 33 | fmap f (ArrEff r) = ArrEff (\b -> do 34 | (c, next) <- r b 35 | return (f c, fmap f next)) 36 | 37 | mArr mf = ArrEff (\b -> do 38 | c <- mf b 39 | return (c, mArr mf)) 40 | 41 | mConst mf = ArrEff (\_ -> do 42 | c <- mf 43 | return (c, mConst mf)) 44 | 45 | aConst c = arr (const c) 46 | 47 | runArrEffList :: Monad m => [c] -> ArrEff m b c -> [b] -> m [c] 48 | runArrEffList cs (ArrEff f) [] = return cs 49 | runArrEffList cs (ArrEff f) (b:bs) = do 50 | (c, next) <- f b 51 | runArrEffList (c:cs) next bs 52 | 53 | runArrEff :: Monad m => ArrEff m b c -> [b] -> m [c] 54 | runArrEff = runArrEffList [] 55 | 56 | runArrEff1 :: Monad m => ArrEff m b c -> b -> m (c, ArrEff m b c) 57 | runArrEff1 (ArrEff f) b = f b 58 | 59 | timesA :: Monad m => Int -> ArrEff m b c -> ArrEff m b [c] 60 | timesA 0 _ = aConst [] 61 | timesA n ar = ArrEff (\b -> do 62 | (c, next) <- runArrEff1 ar b 63 | (cs, next') <- runArrEff1 (timesA (n-1) next) b 64 | return (c:cs, next')) 65 | 66 | forEachA :: Monad m => ArrEff m b () -> ArrEff m [b] () 67 | forEachA ar = ArrEff (\bs -> do 68 | mapM_ (runArrEff1 ar) bs 69 | return ((), aConst ())) 70 | 71 | ------ Arrow for Free language -------------------------------------------------- 72 | type ArrEffFree f b c = ArrEff (Free f) b c 73 | 74 | -- :t says: 75 | -- (Monad m1, Monad m) 76 | -- => (m (c, ArrEff m b c) -> m1 (b1, t)) 77 | -- -> ArrEff m b c 78 | -- -> b 79 | -- -> m1 b1 80 | runFreeArr interpret ar v = do 81 | let p = runArrEff1 ar v 82 | (c, next) <- interpret p -- TODO: what to do with next? 83 | return c 84 | 85 | --------------------- Research stuff ------------------- 86 | 87 | runArrEvent :: Read b => ArrEff IO b (Bool, c) -> [c] -> IO [c] 88 | runArrEvent (ArrEff f) cs = do 89 | b <- getLine 90 | result <- f (read b) 91 | case result of 92 | ((True, c), next) -> runArrEvent next (c:cs) 93 | ((False, c), _) -> return (c:cs) 94 | -------------------------------------------------------------------------------- /Tests/ArrowsAndFrees/ArrowsResearch.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE Arrows #-} 2 | 3 | module ArrowsResearch where 4 | 5 | import Prelude hiding ((.), id) 6 | import Control.Category 7 | import Control.Arrow 8 | 9 | newtype SF b c = SF { runSF :: [b] -> [c] } 10 | 11 | instance Category SF where 12 | id = SF id 13 | SF g . SF f = SF (g . f) 14 | 15 | instance Arrow SF where 16 | arr f = SF (map f) 17 | -- http://stackoverflow.com/questions/28402932/haskell-arrow-delay-function 18 | first (SF f) = SF (unzip >>> first f >>> uncurry zip) 19 | {- 20 | first (SF f) = SF (uncurry zip . (f .*. id) . unzip) 21 | where 22 | (.*.) :: (a -> b) -> (c -> d) -> (a,c) -> (b,d) 23 | (.*.) f g (a,c) = (f a, g c) 24 | -} 25 | 26 | delay x = SF (x:) 27 | 28 | pairPred = arr id &&& delay 0 29 | 30 | testSFArr = do 31 | print $ runSF (arr (+1)) [1..5] 32 | print $ runSF (delay 0) [1..5] 33 | print $ runSF pairPred [1..5] 34 | 35 | ----------------------------------------------------------------------------- 36 | 37 | -- This is actually a stateful stream transducer. 38 | -- See http://stackoverflow.com/questions/4191424/what-are-arrows-and-how-can-i-use-them 39 | newtype MyArr b c = MyArr (b -> (c, MyArr b c)) 40 | 41 | instance Category MyArr where 42 | id = MyArr (\b -> (b, id)) 43 | MyArr g . MyArr f = MyArr arrFG 44 | where 45 | arrFG a = feededF (f a) 46 | feededF (b, arr1) = feededG arr1 (g b) 47 | feededG arr1 (c, arr2) = (c, arr2 . arr1) 48 | 49 | instance Arrow MyArr where 50 | arr f = MyArr (\b -> (f b, arr f)) 51 | first (MyArr f) = MyArr arrF 52 | where 53 | arrF (b, d) = feededF (f b) d 54 | feededF (c, arr1) d = ((c, d), first arr1) 55 | 56 | runArrLst :: MyArr b c -> [b] -> [c] 57 | runArrLst _ [] = [] 58 | runArrLst (MyArr f) (b:bs) = let (c, next) = f b 59 | in c : runArrLst next bs 60 | 61 | countA :: MyArr b Int 62 | countA = count' 0 63 | where 64 | count' n = MyArr (\_ -> (n+1, count' (n+1))) 65 | 66 | showA :: Show b => MyArr b String 67 | showA = MyArr (\b -> (show b, showA)) 68 | 69 | 70 | composedA = showA . countA 71 | 72 | composedA' = proc lst -> do 73 | cnts <- countA -< lst 74 | shs <- showA -< cnts 75 | returnA -< shs 76 | 77 | testMyArr = do 78 | let charsList = ['a'..'z'] 79 | let rs1 = runArrLst showA $ runArrLst countA charsList 80 | putStrLn $ show rs1 81 | 82 | let rs2 = runArrLst composedA charsList 83 | putStrLn $ show rs2 84 | 85 | let rs3 = runArrLst composedA' charsList 86 | putStrLn $ show rs3 87 | 88 | putStrLn $ show $ rs1 == rs2 89 | putStrLn $ show $ rs1 == rs3 -------------------------------------------------------------------------------- /Tests/ArrowsAndFrees/FreeIODSL.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE DeriveFunctor #-} 2 | {-# LANGUAGE ExistentialQuantification #-} 3 | module FreeIODSL where 4 | 5 | import Control.Monad.Trans.Class (lift) 6 | import Control.Monad.Trans.Free 7 | import Control.Monad.Trans.State 8 | import Control.Monad.IO.Class 9 | import qualified Data.Map as M 10 | 11 | data Value = FloatValue Float 12 | | IntValue Int 13 | | StringValue String 14 | deriving (Show, Eq) 15 | 16 | data Property a = Get String (Value -> a) 17 | | Set String Value a 18 | deriving (Functor) 19 | 20 | type ObjectIOF a = FreeT Property IO a 21 | 22 | setP prop val = liftF (Set prop val ()) 23 | getP prop = liftF (Get prop id) 24 | 25 | type Object = M.Map String Value 26 | type Interpreter a = StateT Object IO a 27 | 28 | interpretObject :: ObjectIOF a -> Interpreter a 29 | interpretObject obj = do 30 | x <- liftIO $ runFreeT obj 31 | interpretObject' x 32 | 33 | interpretObject' (Pure a) = return a 34 | interpretObject' (Free a) = interpretProperty a 35 | 36 | --interpretProperty :: Property a -> Interpreter a 37 | interpretProperty (Get prop next) = do 38 | obj <- get 39 | case M.lookup prop obj of 40 | Just v -> interpretObject (next v) 41 | Nothing -> error $ show ("No property", prop) 42 | interpretProperty (Set prop val next) = do 43 | obj <- get 44 | put $ M.insert prop val obj 45 | interpretObject next 46 | 47 | value1 = StringValue "Prop1" 48 | 49 | script :: ObjectIOF Value 50 | script = do 51 | setP "P1" value1 52 | liftIO $ putStrLn "Ho-ho!" 53 | getP "P1" 54 | 55 | test = do 56 | (v, obj) <- runStateT (interpretObject script) M.empty 57 | print $ v == value1 58 | print $ obj == (M.fromList [("P1", value1)]) -------------------------------------------------------------------------------- /Tests/ArrowsAndFrees/Hardware.hs: -------------------------------------------------------------------------------- 1 | module Hardware where 2 | 3 | import HardwareTypes 4 | 5 | import Data.IORef 6 | 7 | initBoosters = do 8 | controllerImpl <- newIORef (ControllerImpl "" Online 0 (map fromIntegral [1..])) 9 | return $ ControllerMock controllerImpl 10 | 11 | reportValue v = print ("reported: " ++ show v) 12 | storeValue v = print ("stored: " ++ show v) 13 | readTemperature (ControllerMock controllerImpl) = do 14 | ControllerImpl _ st n ts <- readIORef controllerImpl 15 | return (head ts) 16 | askStatus _ = return Online 17 | heatUpBoosters (ControllerMock controller) _ _ = do 18 | ControllerImpl _ st n ts <- readIORef controller 19 | writeIORef controller $ ControllerImpl "" st (n + 1) (drop 1 ts) 20 | -------------------------------------------------------------------------------- /Tests/ArrowsAndFrees/HardwareTypes.hs: -------------------------------------------------------------------------------- 1 | module HardwareTypes where 2 | 3 | 4 | import Data.IORef 5 | import Data.Time 6 | 7 | type Name = String 8 | type Duration = DiffTime 9 | data Status = Online | Offline 10 | type Power = Float 11 | type Temperature = Float 12 | 13 | data ControllerImpl = ControllerImpl Name Status Int [Temperature] 14 | data Controller = ControllerMock (IORef ControllerImpl) -------------------------------------------------------------------------------- /Tests/BinaryTreeWithKeys.hs: -------------------------------------------------------------------------------- 1 | 2 | 3 | data Tree = Leaf (Int, Int) | Branch (Int, Int) Tree Tree 4 | deriving (Show) 5 | 6 | 7 | 8 | leftBranch = \(cl, cr) -> 9 | let 10 | ll = cl 11 | lr = cl + (cr - cl) `div` 2 12 | in (ll, lr) 13 | 14 | rightBranch = \(cl, cr) -> 15 | let 16 | rl = cl + (cr - cl) `div` 2 + 1 17 | rr = cr 18 | in (rl, rr) 19 | 20 | 21 | 22 | mkTree :: Int -> (Int, Int) -> Tree 23 | mkTree 0 cur = let 24 | lb = leftBranch cur 25 | rb = rightBranch cur 26 | in Branch cur (Leaf lb) (Leaf rb) 27 | mkTree n cur = let 28 | lb = leftBranch cur 29 | rb = rightBranch cur 30 | in Branch cur (mkTree (n-1) lb) (mkTree (n-1) rb) -------------------------------------------------------------------------------- /Tests/Combinations.hs: -------------------------------------------------------------------------------- 1 | -- http://rosettacode.org/wiki/Combinations#Haskell 2 | 3 | import Data.List (tails) 4 | 5 | comb :: Int -> [a] -> [[a]] 6 | comb 0 _ = [[]] 7 | comb m l = [x:ys | x:xs <- tails l, ys <- comb (m-1) xs] -------------------------------------------------------------------------------- /Tests/Curring.hs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | apply x y = x y 5 | 6 | curringTest = apply show 7 | 8 | main = do 9 | putStrLn (curringTest 1) 10 | 11 | mul x = x * 2 -------------------------------------------------------------------------------- /Tests/Dividing.hs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Tests/Dividing.hs -------------------------------------------------------------------------------- /Tests/DoNotationTest.hs: -------------------------------------------------------------------------------- 1 | data Effect = E String Int 2 | data Cast a = C Effect (Cast a) 3 | type Capability a = Cast a -> a 4 | data Object a = O (Cast a) (Capability a) 5 | 6 | mkActor :: Capability a -> Object a -> Object a 7 | mkActor caps = \(O c1 _) -> O c1 caps 8 | 9 | takeBuff :: Int -> (Cast Int, String) -> Int 10 | takeBuff i (C (E "" eVal) _, _) = i 11 | takeBuff i (C (E eName eVal) c, buffName) | eName == buffName = takeBuff (i + eVal) (c, buffName) 12 | | otherwise = takeBuff i (c, buffName) 13 | 14 | (<~) = takeBuff 15 | 16 | ------------------------------ 17 | 18 | warmable :: Capability Int 19 | warmable c = 10 <~ (c, "warm") 20 | frozenable c = 80 <~ (c, "cold") 21 | 22 | -- WTF?!! How does it work?!!! 23 | box = mkActor $ do 24 | warmable 25 | frozenable 26 | -------------------------------------------------------------------------------- /Tests/ExprParsingTest.hs: -------------------------------------------------------------------------------- 1 | module ParsingTest where 2 | 3 | import Text.Parsec.String 4 | import Text.Parsec.Combinator 5 | import Text.Parsec.Char 6 | import Text.Parsec 7 | 8 | data OpExpr = OpExpr (Char, Int) FPExpr 9 | deriving (Show) 10 | 11 | data FPExpr = IntExpr FPExpr [OpExpr] 12 | | BrackedExpr FPExpr 13 | | Lit String 14 | deriving (Show) 15 | 16 | integer = do 17 | i <- many1 (oneOf ['0'..'9']) 18 | return $ Lit i 19 | 20 | op1 = (char '+', 5) 21 | op2 = (char '*', 4) 22 | op3 = (char '-', 5) 23 | 24 | expr = do 25 | many space 26 | i1 <- integer <|> brackedExpr 27 | exprs <- many opExpr 28 | return $ IntExpr i1 exprs 29 | 30 | op (p, priority) = do 31 | res <- p 32 | return (res, priority) 33 | 34 | opExpr = do 35 | many space 36 | oper <- op op1 <|> op op2 <|> op op3 37 | many space 38 | e <- integer <|> brackedExpr 39 | return $ OpExpr oper e 40 | 41 | brackedExpr :: GenParser Char st FPExpr 42 | brackedExpr = do 43 | e <- between (char '(') (char ')') expr 44 | return $ BrackedExpr e 45 | 46 | str1 = "3 + (2 - 1) * 5" 47 | str2 = "3" 48 | str3 = "3 + 5" 49 | str4 = "(2 - 1) * 5 * 2" 50 | str5 = "1 + 2 * 3" 51 | 52 | test = do 53 | 54 | let result1 = parse expr "" str1 55 | let result2 = parse expr "" str2 56 | let result3 = parse expr "" str3 57 | let result4 = parse expr "" str4 58 | let result5 = parse expr "" str5 59 | 60 | 61 | print result1 62 | print result2 63 | print result3 64 | print result4 65 | print result5 66 | 67 | translate result5 -------------------------------------------------------------------------------- /Tests/Fact.hs: -------------------------------------------------------------------------------- 1 | fact1 0 = 1 2 | fact1 n = fact1 (n-1) * n 3 | 4 | fact2 n | n == 0 = 1 5 | | otherwise = fact2 (n-1) * n 6 | 7 | fact3 n = case n == 0 of 8 | True -> 1 9 | False -> fact3 (n-1) * n 10 | 11 | 12 | fact4 n = case n of 13 | 0 -> 1 14 | _ -> fact4 (n-1) * n 15 | 16 | fact5 n = product [1..n] 17 | 18 | fact6 n = if n == 0 19 | then 1 20 | else n * fact5 (n-1) -------------------------------------------------------------------------------- /Tests/FactAndFib.hs: -------------------------------------------------------------------------------- 1 | module Main where 2 | 3 | import Data.Word 4 | 5 | fib :: Word -> Word 6 | fib 0 = 0 7 | fib 1 = 1 8 | fib n = fib (n-1) + fib (n-2) 9 | 10 | fact :: Word -> Word 11 | fact 0 = 1 12 | fact n = fact (n-1) * n -------------------------------------------------------------------------------- /Tests/FailureProbability/FailureProbability.hs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Tests/FailureProbability/FailureProbability.hs -------------------------------------------------------------------------------- /Tests/FailureProbability/compile.cmd: -------------------------------------------------------------------------------- 1 | del *.hi 2 | del *.o 3 | del FailureProbability.exe 4 | 5 | ghc -O2 FailureProbability.hs -rtsopts -threaded 6 | -------------------------------------------------------------------------------- /Tests/FailureProbability/run.cmd: -------------------------------------------------------------------------------- 1 | FailureProbability.exe +RTS -K134217728 -RTS -------------------------------------------------------------------------------- /Tests/Fib.hs: -------------------------------------------------------------------------------- 1 | fib :: Int -> Int 2 | fib 0 = 0 3 | fib 1 = 1 4 | fib n = fib (n-1) + fib (n-2) -------------------------------------------------------------------------------- /Tests/FinanceTree.hs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Tests/FinanceTree.hs -------------------------------------------------------------------------------- /Tests/FizzBuzz.hs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Tests/FizzBuzz.hs -------------------------------------------------------------------------------- /Tests/FizzBuzz2.hs: -------------------------------------------------------------------------------- 1 | module Main where 2 | 3 | main :: IO () 4 | main = do 5 | putStrLn "Printing FizzBuzzes..." 6 | mapM_ putStrLn fizzBuzzes 7 | 8 | 9 | 10 | fizzBuzzes :: [String] 11 | fizzBuzzes = iterateList [1..100] 12 | iterateList :: [Int] -> [String] 13 | iterateList [] = [] 14 | iterateList (x : xs) = fizzBuzz x : iterateList xs 15 | 16 | 17 | fizzBuzzes' :: [String] 18 | fizzBuzzes' = accumulate' 1 19 | accumulate' :: Int -> [String] 20 | accumulate' 100 = [ fizzBuzz 100 ] 21 | accumulate' n = fizzBuzz n : accumulate' (n + 1) 22 | 23 | 24 | fizzBuzz :: Int -> String 25 | fizzBuzz x | isDivided x 15 = "FizzBuzz" 26 | | isDivided x 5 = "Buzz" 27 | | isDivided x 3 = "Fizz" 28 | | otherwise = show x 29 | 30 | fizzBuzz' :: Int -> String 31 | fizzBuzz' x = case isDivided x 15 of 32 | True -> "FizzBuzz" 33 | False -> case isDivided x 5 of 34 | True -> "Buzz" 35 | False -> case isDivided x 3 of 36 | True -> "Fizz" 37 | False -> show x 38 | 39 | isDivided :: Int -> Int -> Bool 40 | isDivided x n = (x `mod` n) == 0 -------------------------------------------------------------------------------- /Tests/FizzBuzz3.hs: -------------------------------------------------------------------------------- 1 | module Main where 2 | 3 | fizzBuzz :: Int -> String 4 | 5 | fizzBuzz x | isDivided x 15 = "FizzBuzz" 6 | | isDivided x 5 = "Buzz" 7 | | isDivided x 3 = "Fizz" 8 | | otherwise = show x 9 | 10 | 11 | isDivided :: Int -> Int -> Bool 12 | isDivided x n = (x `mod` n) == 0 13 | 14 | isDivided' :: Int -> (Int -> Bool) 15 | isDivided' x = \n -> (x `mod` n) == 0 16 | 17 | isDivided'' :: (Int -> Int -> Bool) 18 | isDivided'' = \x n -> (x `mod` n) == 0 19 | 20 | fizzBuzzes :: [String] 21 | fizzBuzzes = map fizzBuzz [1..100] 22 | 23 | 24 | -------------------------------------------------------------------------------- /Tests/FizzBuzz4.hs: -------------------------------------------------------------------------------- 1 | module Main where 2 | 3 | main = do 4 | putStrLn "Printing FizzBuzzes..." 5 | print fizzBuzzes 6 | 7 | fizzBuzzes = map fizzBuzz [1..100] 8 | 9 | fizzBuzz x | isDivided x 15 = "FizzBuzz" 10 | | isDivided x 5 = "Buzz" 11 | | isDivided x 3 = "Fizz" 12 | | otherwise = show x 13 | 14 | isDivided x n = (x `mod` n) == 0 15 | 16 | 17 | hello :: IO () 18 | hello = do 19 | putStrLn "What is your name?" 20 | yourName <- getLine 21 | putStr "Hello, " 22 | putStrLn (yourName ++ "!") -------------------------------------------------------------------------------- /Tests/FizzBuzz5.hs: -------------------------------------------------------------------------------- 1 | module Main where 2 | 3 | import Data.Char (toLower) 4 | 5 | fizzBuzz :: Int -> String 6 | fizzBuzz x | (x `mod` 15) == 0 = "FizzBuzz" 7 | | (x `mod` 5) == 0 = "Buzz" 8 | | (x `mod` 3) == 0 = "Fizz" 9 | | otherwise = show x 10 | 11 | morseCode :: [(Char, String)] 12 | morseCode = 13 | [ ('b', "-..."), ('f', "..-."), ('i', ".."), ('u', "..-") 14 | , ('z', "--.."), ('0', "-----"), ('1', ".----"), ('2', "..---") 15 | , ('3', "...--"), ('4', "....-"), ('5', "....."), ('6', "-....") 16 | , ('7', "--..."), ('8', "---.."), ('9', "----.") ] 17 | 18 | toMorse :: Char -> String 19 | toMorse char = case lookup char morseCode of 20 | Just code -> code 21 | Nothing -> "???" 22 | 23 | morseBelt :: Int -> [String] 24 | morseBelt = map (' ' :) . map toMorse . map toLower . fizzBuzz 25 | 26 | morseFizzBuzzes :: String 27 | morseFizzBuzzes = (concat . concatMap morseBelt) [1..100] 28 | 29 | main = do 30 | putStrLn morseFizzBuzzes 31 | 32 | putStrLn helloWorld1 33 | 34 | 35 | prependSpace :: [Char] -> [Char] 36 | prependSpace = (' ':) 37 | 38 | appendWord :: Char -> [Char] 39 | appendWord = (:"World") 40 | 41 | helloWorld1 = "Hello," ++ (prependSpace "World") 42 | helloWorld2 = "Hello," ++ (appendWord ' ') 43 | 44 | hello = 'H' : 'e' : 'l' : 'l' : 'o' : [] 45 | 46 | -- all these functions have type (Int -> String) 47 | toLowerFizzBuzz1 = map toLower . fizzBuzz -- eta-conversion 48 | toLowerFizzBuzz2 n = (map toLower . fizzBuzz) n 49 | toLowerFizzBuzz3 n = map toLower . fizzBuzz $ n 50 | toLowerFizzBuzz4 n = map toLower (fizzBuzz n) 51 | toLowerFizzBuzz5 n = map toLower $ fizzBuzz n 52 | toLowerFizzBuzz6 n = map toLower $ fizzBuzz $ n 53 | 54 | -------------------------------------------------------------------------------- /Tests/FizzBuzz6Free.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE DeriveFunctor #-} 2 | 3 | import Control.Monad.Free 4 | 5 | data FizzBuzz a = GetFizz Int Int (String -> a) 6 | | GetBuzz Int Int (String -> a) 7 | | GetNum Int Int (String -> a) 8 | -- deriving (Functor) 9 | 10 | type FizzBuzzer a = Free FizzBuzz a 11 | 12 | instance Functor FizzBuzz where 13 | fmap f (GetFizz n m next) = GetFizz n m (fmap f next) 14 | fmap f (GetBuzz n m next) = GetBuzz n m (fmap f next) 15 | fmap f (GetNum n m next) = GetNum n m (fmap f next) 16 | 17 | getFizz, getBuzz, getNum :: Int -> Int -> FizzBuzzer String 18 | getFizz n m = liftF (GetFizz n m id) 19 | getBuzz n m = liftF (GetBuzz n m id) 20 | getNum z n = liftF (GetNum z n id) 21 | 22 | 23 | getFizz', getBuzz', getNum' :: Int -> Int -> FizzBuzzer String 24 | getFizz' n m = Free (GetFizz n m Pure) 25 | getBuzz' n m = Free (GetBuzz n m Pure) 26 | getNum' z n = Free (GetNum z n Pure) 27 | 28 | getFizzBuzz :: Int -> FizzBuzzer String 29 | getFizzBuzz n = do 30 | fizz <- getFizz n 5 31 | buzz <- getBuzz n 3 32 | let fb = fizz ++ buzz 33 | s <- getNum (length fb) n 34 | return $ s ++ fizz ++ buzz 35 | 36 | interpret :: FizzBuzzer String -> String 37 | interpret (Pure a) = a 38 | interpret (Free fb) = case fb of 39 | GetFizz n m next -> interpret $ next $ if n `mod` m == 0 then "Fizz" else "" 40 | GetBuzz n m next -> interpret $ next $ if n `mod` m == 0 then "Buzz" else "" 41 | GetNum 0 n next -> interpret $ next $ show n 42 | GetNum _ _ next -> interpret $ next $ "" 43 | 44 | main = do 45 | let fizzBuzzes = map (interpret . getFizzBuzz) [1..15] 46 | mapM_ print fizzBuzzes 47 | -------------------------------------------------------------------------------- /Tests/Fractal/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | /Programs/BlueFont/p_text.txt 3 | /Programs/BlueFont/text.txt 4 | /Exercises/output.txt 5 | /Exercises/perms2.txt 6 | /Exercises/permutations.txt -------------------------------------------------------------------------------- /Tests/Fractal/FractalComonad.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE DeriveFunctor #-} 2 | module FractalComonad where 3 | 4 | import Control.Comonad 5 | import Control.Applicative 6 | 7 | data Layer a = Layer a 8 | deriving (Show, Read, Eq, Functor) 9 | 10 | instance Comonad Layer where 11 | -- duplicate :: w a -> w (w a) 12 | duplicate (Layer l) = Layer (Layer l) 13 | -- extract :: w a -> a 14 | extract (Layer l) = l 15 | 16 | 17 | checkComLaws1 = (extract . duplicate $ cantorLayer) == cantorLayer 18 | checkComLaws2 = (fmap extract . duplicate $ cantorLayer) == cantorLayer 19 | checkComLaws3 = (duplicate . duplicate $ cantorLayer) == (fmap duplicate . duplicate $ cantorLayer) 20 | cLaws = [checkComLaws1, checkComLaws2, checkComLaws3] 21 | 22 | comonadCantorRule :: Layer Segments -> Segments 23 | comonadCantorRule = cantorGen . extract 24 | 25 | 26 | type Segment = (Float, Float) 27 | type Segments = [(Float, Float)] 28 | 29 | cantorRule :: Segment -> Segments 30 | cantorRule (x1, x2) = let 31 | len = x2 - x1 32 | oneThird = len / 3.0 33 | in [(x1, x1 + oneThird), (x2 - oneThird, x2)] 34 | 35 | cantorGen :: Segments -> Segments 36 | cantorGen segs = concatMap cantorRule segs 37 | 38 | fractal' :: [Segments] 39 | fractal' = iterate cantorGen [(0.0, 0.9)] 40 | 41 | 42 | cantorStartSegment x1 x2 = [(x1, x2)] 43 | 44 | cantorLayer = mkCantor 0.0 9.0 45 | mkCantor :: Float -> Float -> Layer Segments 46 | mkCantor x1 x2 = Layer $ cantorStartSegment x1 x2 47 | 48 | comonadCantorGen :: Layer Segments -> Layer Segments 49 | comonadCantorGen layer = comonadCantorRule `extend` layer 50 | 51 | fractal = iterate comonadCantorGen cantorLayer 52 | 53 | {- LYAH -} 54 | {- 55 | 56 | > class Functor w => Comonad w where 57 | > extract :: w a -> a 58 | > duplicate :: w a -> w (w a) 59 | > extend :: (w a -> b) -> w a -> w b 60 | > extend f = fmap f . duplicate 61 | > duplicate = extend id 62 | 63 | data Tree a = Empty | Node a (Tree a) (Tree a) 64 | deriving (Show) 65 | 66 | data TreeZ a = L a (Tree a) 67 | | R a (Tree a) 68 | deriving (Show) 69 | 70 | type TreeZS a = [TreeZ a] 71 | type TreeZipper a = (Tree a, TreeZS a) 72 | 73 | left, right :: TreeZipper a -> TreeZipper a 74 | left (Node x l r, bs) = (l, L x r:bs) 75 | right (Node x l r, bs) = (r, R x l:bs) 76 | 77 | type CantorTree = Tree Segment 78 | genLSegment x = Node (head $ cantorGen x) Empty Empty 79 | genRSegment x = Node (head $ tail $ cantorGen x) Empty Empty 80 | cantorLeft (Node x Empty r, bs) = (genLSegment x, L x r : bs) 81 | cantorLeft (Node x l r, bs) = (l, L x r : bs) 82 | cantorRight (Node x l Empty, bs) = (genRSegment x, R x l : bs) 83 | 84 | -} 85 | -------------------------------------------------------------------------------- /Tests/Fractal/FractalOfFrcactals.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE DeriveFunctor #-} 2 | module FractalComonad where 3 | 4 | import Control.Comonad 5 | import Control.Applicative 6 | 7 | data Layer a = Layer a 8 | deriving (Show, Read, Eq, Functor) 9 | 10 | instance Comonad Layer where 11 | -- duplicate :: w a -> w (w a) 12 | duplicate (Layer l) = Layer (Layer l) 13 | -- extract :: w a -> a 14 | extract (Layer l) = l 15 | 16 | 17 | checkComLaws1 = (extract . duplicate $ test) == test 18 | checkComLaws2 = (fmap extract . duplicate $ test) == test 19 | checkComLaws3 = (duplicate . duplicate $ test) == (fmap duplicate . duplicate $ test) 20 | cLaws = [checkComLaws1, checkComLaws2, checkComLaws3] 21 | 22 | comonadCantorRule :: Layer Segments -> Segments 23 | comonadCantorRule layer = --concatMap cantorRule . extract 24 | let segments = extract layer 25 | in concatMap cantorRule segments 26 | 27 | 28 | type Segment = (Float, Float) 29 | type Segments = [(Float, Float)] 30 | 31 | cantorRule :: Segment -> Segments 32 | cantorRule (x1, x2) = let 33 | len = x2 - x1 34 | oneThird = len / 3.0 35 | in [(x1, x1 + oneThird), (x2 - oneThird, x2)] 36 | 37 | 38 | cantorCustomGen :: Segments -> Segments 39 | cantorCustomGen segs = concatMap cantorRule segs 40 | 41 | 42 | cantorStartSegment x1 x2 = [(x1, x2)] 43 | 44 | test = mkCantor 0.0 9.0 45 | mkCantor :: Float -> Float -> Layer Segments 46 | mkCantor x1 x2 = Layer $ cantorStartSegment x1 x2 47 | cantorGen = (=>> comonadCantorRule) 48 | fractal = iterate cantorGen test 49 | 50 | {- LYAH -} 51 | {- 52 | data Tree a = Empty | Node a (Tree a) (Tree a) 53 | deriving (Show) 54 | 55 | data TreeZ a = L a (Tree a) 56 | | R a (Tree a) 57 | deriving (Show) 58 | 59 | type TreeZS a = [TreeZ a] 60 | type TreeZipper a = (Tree a, TreeZS a) 61 | 62 | left, right :: TreeZipper a -> TreeZipper a 63 | left (Node x l r, bs) = (l, L x r:bs) 64 | right (Node x l r, bs) = (r, R x l:bs) 65 | 66 | type CantorTree = Tree Segment 67 | genLSegment x = Node (head $ cantorGen x) Empty Empty 68 | genRSegment x = Node (head $ tail $ cantorGen x) Empty Empty 69 | cantorLeft (Node x Empty r, bs) = (genLSegment x, L x r : bs) 70 | cantorLeft (Node x l r, bs) = (l, L x r : bs) 71 | cantorRight (Node x l Empty, bs) = (genRSegment x, R x l : bs) 72 | 73 | -} 74 | -------------------------------------------------------------------------------- /Tests/Fractal/FractalWithData.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE DeriveFunctor #-} 2 | module FractalComonad where 3 | 4 | import Control.Comonad 5 | import Control.Applicative 6 | 7 | data Layer a = Layer a 8 | deriving (Show, Read, Eq, Functor) 9 | 10 | instance Comonad Layer where 11 | -- duplicate :: w a -> w (w a) 12 | duplicate (Layer l) = Layer (Layer l) 13 | -- extract :: w a -> a 14 | extract (Layer l) = l 15 | 16 | 17 | checkComLaws1 = (extract . duplicate $ cantorLayer) == cantorLayer 18 | checkComLaws2 = (fmap extract . duplicate $ cantorLayer) == cantorLayer 19 | checkComLaws3 = (duplicate . duplicate $ cantorLayer) == (fmap duplicate . duplicate $ cantorLayer) 20 | cLaws = [checkComLaws1, checkComLaws2, checkComLaws3] 21 | 22 | comonadCantorRule :: Layer Segments -> Segments 23 | comonadCantorRule layer = concatMap cantorRule . extract 24 | let segments = extract layer 25 | in concatMap cantorRule segments 26 | 27 | 28 | type Segment = (Float, Float) 29 | type Segments = [(Float, Float)] 30 | 31 | cantorRule :: Segment -> Segments 32 | cantorRule (x1, x2) = let 33 | len = x2 - x1 34 | oneThird = len / 3.0 35 | in [(x1, x1 + oneThird), (x2 - oneThird, x2)] 36 | 37 | 38 | cantorCustomGen :: Segments -> Segments 39 | cantorCustomGen segs = concatMap cantorRule segs 40 | 41 | fractal' :: [Segments] 42 | fractal' = iterate cantorCustomGen [(0.0, 0.9)] 43 | 44 | 45 | cantorStartSegment x1 x2 = [(x1, x2)] 46 | 47 | cantorLayer = mkCantor 0.0 9.0 48 | mkCantor :: Float -> Float -> Layer Segments 49 | mkCantor x1 x2 = Layer $ cantorStartSegment x1 x2 50 | 51 | comonadCantorGen :: Layer Segments -> Layer Segments 52 | comonadCantorGen = (=>> comonadCantorRule) 53 | 54 | fractal = iterate comonadCantorGen cantorLayer 55 | 56 | {- LYAH -} 57 | {- 58 | data Tree a = Empty | Node a (Tree a) (Tree a) 59 | deriving (Show) 60 | 61 | data TreeZ a = L a (Tree a) 62 | | R a (Tree a) 63 | deriving (Show) 64 | 65 | type TreeZS a = [TreeZ a] 66 | type TreeZipper a = (Tree a, TreeZS a) 67 | 68 | left, right :: TreeZipper a -> TreeZipper a 69 | left (Node x l r, bs) = (l, L x r:bs) 70 | right (Node x l r, bs) = (r, R x l:bs) 71 | 72 | type CantorTree = Tree Segment 73 | genLSegment x = Node (head $ cantorGen x) Empty Empty 74 | genRSegment x = Node (head $ tail $ cantorGen x) Empty Empty 75 | cantorLeft (Node x Empty r, bs) = (genLSegment x, L x r : bs) 76 | cantorLeft (Node x l r, bs) = (l, L x r : bs) 77 | cantorRight (Node x l Empty, bs) = (genRSegment x, R x l : bs) 78 | 79 | -} 80 | -------------------------------------------------------------------------------- /Tests/GameOfLife.hs: -------------------------------------------------------------------------------- 1 | module Main where 2 | 3 | import qualified Data.List as L 4 | 5 | type Cell = (Int, Int) 6 | type Shape = [Cell] 7 | 8 | tripleOscilator :: Shape 9 | tripleOscilator = [ (0, 0) 10 | , (0, 1) 11 | , (0, 2) 12 | ] 13 | 14 | glider :: Shape 15 | glider = [ (0, 0) 16 | , (1, 0) 17 | , (2, 0) 18 | , (2, 1) 19 | , (1, 2) 20 | ] 21 | 22 | shift :: Cell -> Shape -> Shape 23 | shift (dx, dy) = map (\(x, y) -> (x + dx, y + dy)) 24 | 25 | (>|<) :: Shape -> Shape -> Shape 26 | sh1 >|< sh2 = L.nub (sh1 ++ sh2) 27 | 28 | iterations :: Shape -> [Shape] 29 | iterations pos = pos : iterations (step pos) 30 | 31 | neighbours8 cell cells = cells `L.intersect` (box8 cell) 32 | 33 | box8 (ax, ay) = [(x,y) | x <- range ax, y <- range ay, (ax,ay) /= (x,y)] 34 | lim n = [n - 1, n + 1] 35 | range n = [n - 1, n, n + 1] 36 | 37 | step :: Shape -> Shape 38 | step p = let 39 | next all [] = [] 40 | next all cur@((aX, aY) : alives) = 41 | [(x, y) | x <- lim aX, y <- lim aY, 42 | length (neighbours8 (x, y) all) == 3] 43 | ++ (next all alives) 44 | alive all cell = length (neighbours8 cell all) `elem` [2,3] 45 | in L.nub $ filter (alive p) p ++ (next p p) 46 | 47 | 48 | whileAlive :: Shape -> [Shape] 49 | whileAlive p = let next = step p 50 | in if (next == p) 51 | then p : [] 52 | else p : whileAlive next 53 | 54 | 55 | -------------------------------------------------------------------------------- /Tests/HaskellSkbRii/Task1/FizzBuzz.hs: -------------------------------------------------------------------------------- 1 | {- 2 | Напишите программу, которая выводит на экран числа от 1 до 100. 3 | При этом вместо чисел, кратных трем, программа должна выводить 4 | слово «Fizz», а вместо чисел, кратных пяти — слово «Buzz». 5 | Если число кратно и 3, и 5, то программа должна выводить слово «FizzBuzz» 6 | -} 7 | 8 | module Main where 9 | 10 | fizzBuzz :: Int -> String 11 | fizzBuzz = undefined 12 | 13 | main = do 14 | let myFizzBuzzes = --put your solution here 15 | 16 | fbs <- readFile "FizzBuzzes.txt" 17 | if read fbs == myFizzBuzzes 18 | then putStrLn "Right." 19 | else putStrLn "Not right." 20 | -------------------------------------------------------------------------------- /Tests/HaskellSkbRii/Task1/FizzBuzzes.txt: -------------------------------------------------------------------------------- 1 | ["1","2","Fizz","4","Buzz","Fizz","7","8","Fizz","Buzz","11","Fizz","13","14","FizzBuzz","16","17","Fizz","19","Buzz","Fizz","22","23","Fizz","Buzz","26","Fizz","28","29","FizzBuzz","31","32","Fizz","34","Buzz","Fizz","37","38","Fizz","Buzz","41","Fizz","43","44","FizzBuzz","46","47","Fizz","49","Buzz","Fizz","52","53","Fizz","Buzz","56","Fizz","58","59","FizzBuzz","61","62","Fizz","64","Buzz","Fizz","67","68","Fizz","Buzz","71","Fizz","73","74","FizzBuzz","76","77","Fizz","79","Buzz","Fizz","82","83","Fizz","Buzz","86","Fizz","88","89","FizzBuzz","91","92","Fizz","94","Buzz","Fizz","97","98","Fizz","Buzz"] -------------------------------------------------------------------------------- /Tests/HaskellSkbRii/Task2/BlankSolver.hs: -------------------------------------------------------------------------------- 1 | {- Дано конечное ограниченное поле 5х5, в каждой ячейке которого имеется одна стрелка: вверх, вниз, вправо или влево. 2 | На позицию (x1, y1) помещается робот Тинк. 3 | На позицию (x2, y2) помещается роботиха Кики. 4 | Тинк движется по полю. У него и у Кики энергии хватит максимум на 10 шагов. 5 | Стрелка, на которую зашел Тинк, указывает Кики, куда ей двигаться. 6 | Если движение невозможно (за край поля выйти нельзя), Кики остается на месте. 7 | 8 | Задача: найти (любой) путь Тинка, когда роботы встречаются на одной клетке. 9 | 10 | Пример решения за 8 ходов: 11 | 12 | solutionPath :: Path 13 | solutionPath = [ ((0,0), (4,4)) 14 | , ((1,0), (3,4)) 15 | , ((0,0), (2,4)) 16 | , ((0,1), (2,3)) 17 | , ((0,0), (1,3)) 18 | , ((0,1), (1,2)) 19 | , ((0,2), (0,2)) 20 | ] 21 | -} 22 | 23 | module BlankSolver where 24 | 25 | import TinkAndKiki 26 | 27 | solve :: Path 28 | solve = undefined 29 | 30 | 31 | -------------------------------------------------------------------------------- /Tests/HaskellSkbRii/Task2/Solution8.txt: -------------------------------------------------------------------------------- 1 | [((0,0),(4,4)),((1,0),(3,4)),((0,0),(2,4)),((0,1),(2,3)),((0,0),(1,3)),((0,1),(1,2)),((0,2),(0,2))] -------------------------------------------------------------------------------- /Tests/HaskellSkbRii/Task2/TinkAndKiki.hs: -------------------------------------------------------------------------------- 1 | module TinkAndKiki where 2 | 3 | type Arrow = Char 4 | type Field = [[Arrow]] 5 | 6 | type Position = (Int, Int) 7 | type Positions = [Position] 8 | type Dislocation = (Position, Position) 9 | 10 | type Path = [Dislocation] 11 | type Paths = [Path] 12 | 13 | u, d, l, r :: Char 14 | u = 'u' 15 | d = 'd' 16 | l = 'l' 17 | r = 'r' 18 | 19 | field :: Field 20 | field = [ [u, l, u, r, l] 21 | , [u, d, d, r, r] 22 | , [l, r, r, l, l] 23 | , [d, r, u, u, u] 24 | , [d, d, r, l, u] ] 25 | 26 | energyLimit = 10 27 | 28 | tinkStart, kikiStart :: Position 29 | tinkStart = (0, 0) 30 | kikiStart = (4, 4) 31 | 32 | startPositions :: Dislocation 33 | startPositions = (tinkStart, kikiStart) 34 | 35 | 36 | -------------------------------------------------------------------------------- /Tests/HaskellSkbRii/Task3/Interpreter.hs: -------------------------------------------------------------------------------- 1 | module Interpreter where 2 | 3 | import Language 4 | 5 | data Result = StrResult String 6 | | IntResult Int 7 | | CharResult Char 8 | | OperationResult Operation 9 | | SequenceResult Result Result 10 | | Eval (IO ()) 11 | 12 | evalMath Increment (IntResult i) = IntResult $ i + 1 13 | evalMath Decrement (IntResult i) = IntResult $ i - 1 14 | evalMath (Multiply n) (IntResult i) = IntResult $ i * n 15 | evalMath m _ = Eval $ putStr $ "Invalid argument for math " ++ show m 16 | 17 | evalGetChar (IntResult i) (StrResult str) | length str > i = CharResult (str !! i) 18 | | otherwise = Eval $ putStr $ "Index out of bounds: " ++ show i 19 | evalGetChar _ _ = Eval $ putStr "Invalid GetChar arguments." 20 | 21 | evalSCombinator (OperationResult op) r = interpret op r 22 | evalSCombinator _ _ = Eval $ putStr "Invalid operation for S combinator." 23 | 24 | -- | Interpreter 25 | interpret NoOperation _ = Eval $ putStrLn "No operation." 26 | interpret GetLength (StrResult str) = IntResult (length str) 27 | interpret GetLength (CharResult _) = Eval (putStr "Invalid operation: can't get length of char value.") 28 | interpret GetLength (IntResult i) = Eval (putStr "Invalid operation: can't get length of int value.") 29 | interpret GetLength (Eval _) = Eval (putStr "Invalid operation: can't get length of this value.") 30 | interpret GetLength (OperationResult _) = Eval (putStr "Invalid operation: can't get length of Operation value.") 31 | interpret GetLength (SequenceResult _ _) = Eval (putStr "Invalid operation: can't get length of Sequence value.") 32 | 33 | interpret (GetCharAt op) d@(StrResult str) = let 34 | idx = interpret op d 35 | in evalGetChar idx d 36 | interpret (GetCharAt _) (IntResult i) = Eval $ putStr "Invalid operation: can't extract char of int value." 37 | interpret (GetCharAt _) (CharResult i) = Eval $ putStr "Invalid operation: can't extract char of char value." 38 | interpret (GetCharAt _) (Eval _) = Eval $ putStr "Invalid operation: can't extract char of this value." 39 | interpret (GetCharAt _) (OperationResult _) = Eval $ putStr "Invalid operation: can't extract char of Operation value." 40 | interpret (GetCharAt _) (SequenceResult _ _) = Eval $ putStr "Invalid operation: can't extract char of Sequence value." 41 | 42 | interpret (ReturnString str) _ = StrResult str 43 | 44 | interpret (Sequence op1 op2) d = let 45 | res1 = interpret op1 d 46 | res2 = interpret op2 d 47 | in SequenceResult res1 res2 48 | 49 | interpret (ApplyMath math op) d = let 50 | x = interpret op d 51 | in evalMath math x 52 | 53 | interpret (Apply op2 op1) d = let 54 | res = interpret op1 d 55 | in interpret op2 res 56 | 57 | interpret (K op) _ = OperationResult op 58 | interpret I d = d 59 | interpret (S op1 op2) d = let 60 | h = interpret op1 d 61 | y = interpret op2 d 62 | in evalSCombinator h y 63 | 64 | -- | Result evaluator 65 | eval (Eval act) = act 66 | eval (IntResult i) = putStr $ show i 67 | eval (CharResult c) = putStr $ show c 68 | eval (StrResult s) = putStr s 69 | eval (OperationResult op) = putStr $ "Operation result is not finished: " ++ show op 70 | eval (SequenceResult r1 r2) = eval r1 >> eval r2 71 | -------------------------------------------------------------------------------- /Tests/HaskellSkbRii/Task3/Language.hs: -------------------------------------------------------------------------------- 1 | module Language where 2 | 3 | data Math = Increment 4 | | Decrement 5 | | Multiply Int 6 | deriving (Show, Read) 7 | 8 | data Operation = Apply Operation Operation 9 | | GetLength 10 | | ApplyMath Math Operation 11 | | GetCharAt Operation 12 | | NoOperation 13 | | Sequence Operation Operation 14 | | ReturnString String 15 | | K Operation 16 | | S Operation Operation 17 | | I 18 | deriving (Show, Read) 19 | 20 | type Operations = [Operation] 21 | 22 | -- Apply :: op1 -> op2 -> d -> res 23 | -- Apply takes the second argument, applies to the third one, 24 | -- then applies the first argument to the previous result. It acts like so: 25 | -- Apply op2 op1 d = let 26 | -- res1 = op1 d 27 | -- res2 = op2 res 28 | -- in res2 29 | 30 | -- ApplyMath takes the second argument, applies to the third one, 31 | -- then tries to eval math equation with the previous result. It acts like so: 32 | -- ApplyMath :: Math -> op -> d -> res 33 | -- ApplyMath math op d = let 34 | -- res1 = op d 35 | -- res2 = evalMath math res1 36 | -- in res2 37 | 38 | -- GetLength :: String -> Int 39 | 40 | -- GetCharAt :: (String -> Int) -> String -> Char 41 | -- GetCharAt takes 2 arguments: some function f and string. 42 | -- GetCharAt applies f to string, which result is integer index. 43 | -- Then GetCharAt extracts a char from that string at that index. 44 | 45 | -- PrintMe :: String -> a -> b 46 | -- PrintMe ignores it's second parameter and just prints some string. 47 | 48 | -- ReturnString :: String -> a -> b 49 | -- ReturnString ignores it's second parameter, but allowes the first argument 50 | -- to use as string in computations. 51 | 52 | -- Sequence :: (String -> a) -> (String -> b) -> String -> [a, b] 53 | -- Sequence: applies both operations to the input parameter separately. Example: 54 | -- (Sequence (PrintMe "Hello, ") (PrintMe "World!")) => "Hello, World!" 55 | 56 | -- I just returns its argument as is. It acts like so: 57 | -- I x = x 58 | -- K takes 2 arguments: function and some argument. 59 | -- K ignores its second argument and returns the first one. It acts like so: 60 | -- K a b = a 61 | -- S recives 3 arguments: a, b, x. It acts like so: 62 | -- S a b x = let 63 | -- h = a x 64 | -- y = b x 65 | -- result = h y 66 | -- in result 67 | -- The last result value is result of S. 68 | 69 | -- S, K, I: http://en.wikipedia.org/wiki/SKI_combinator_calculus 70 | -------------------------------------------------------------------------------- /Tests/HaskellSkbRii/Task3/TestInput.txt: -------------------------------------------------------------------------------- 1 | [ ReturnString "This is string." 2 | , GetCharAt GetLength 3 | , S (K (ApplyMath Decrement I)) GetLength 4 | , Sequence (ReturnString "Hello, ") (ReturnString "World!") 5 | , Apply GetLength (ReturnString "ABCD") 6 | ] 7 | -------------------------------------------------------------------------------- /Tests/HighOrderFuncs.hs: -------------------------------------------------------------------------------- 1 | module Main where 2 | 3 | 4 | numberList = [1, 2, 3, 4, 5] 5 | 6 | modifyList func list = map func list 7 | 8 | square x = x * x 9 | double x = 2 * x 10 | zero x = 0 11 | 12 | squares = modifyList square numberList 13 | doubles = modifyList double numberList 14 | zeros = modifyList zero numberList -------------------------------------------------------------------------------- /Tests/InfSum.hs: -------------------------------------------------------------------------------- 1 | 2 | 3 | s = map (\x -> 1 / x^2) [1, 2..] 4 | 5 | s' = sum (take 1000000 s) -------------------------------------------------------------------------------- /Tests/Kleisli.hs: -------------------------------------------------------------------------------- 1 | import Data.Char 2 | import Data.List 3 | 4 | -- test' :: String -> IO () 5 | -- test' = runKleisli (Klesli purStrLn . arr (map toUpper) . Kleisli readFile) 6 | 7 | test :: String -> IO () 8 | test = (putStrLn =<<) . fmap (map toUpper) . readFile 9 | 10 | test2 = fmap (putStrLn . map toUpper) . readFile 11 | 12 | main = test2 "LICENSE" -------------------------------------------------------------------------------- /Tests/Language.hs: -------------------------------------------------------------------------------- 1 | module Main where 2 | 3 | import Language.Haskell.Parser 4 | import System 5 | 6 | main = do 7 | args <- getArgs 8 | case args of 9 | (a:_) -> do 10 | s <- readFile a 11 | let parsed = parseModule s 12 | putStrLn . show $ parsed 13 | writeFile (a ++ ".parsed.txt") (show parsed) 14 | _ -> putStrLn "Please, select a file." 15 | -------------------------------------------------------------------------------- /Tests/Lessons/ListFold.hs: -------------------------------------------------------------------------------- 1 | 2 | 3 | sumList [] = 0 4 | sumList (x:xs) = x + sumList xs 5 | 6 | sumList' xs = foldr (+) 0 xs 7 | 8 | -------------------------------------------------------------------------------- /Tests/Lessons/ListMap.hs: -------------------------------------------------------------------------------- 1 | 2 | import Data.Char 3 | 4 | l1 = [1, 1, 2, 3, 5] 5 | 6 | mul x n = x * n 7 | pow x n = x ^ n 8 | 9 | doubleList = map (*2) l1 10 | doubleList' = map (\x -> x * 2) l1 11 | doubleList'' = map (mul 2) l1 12 | doubleList''' = map (\x -> mul 2 x) l1 13 | 14 | squareList = map (^2) l1 15 | squareList' = map (\x -> x * x) l1 16 | squareList'' = map (\x -> pow x 2) l1 17 | 18 | powerOfTwo = map (2^) l1 19 | powerOfTwo' = map (\x -> 2 ^ x) l1 20 | powerOfTwo'' = map (pow 2) l1 21 | powerOfTwo''' = map (\x -> pow 2 x) l1 22 | 23 | 24 | upperString [] = [] 25 | upperString (s:ss) = toUpper s : upperString ss 26 | 27 | upperString' ss = map toUpper ss 28 | 29 | upperString'' ss = map toUpper -------------------------------------------------------------------------------- /Tests/Lessons/Structure.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graninas/Haskell-Algorithms/ea33607b3af50d5df09513ed9e99a9faa712f57b/Tests/Lessons/Structure.txt -------------------------------------------------------------------------------- /Tests/ListManipulation.hs: -------------------------------------------------------------------------------- 1 | import Data.List 2 | import Criterion.Main (defaultMain, bench, whnf) 3 | 4 | takeInterest :: [String] -> [Int] -> [String] 5 | takeInterest _ [] = [] 6 | takeInterest ss (n:ns) = [ss !! n] ++ takeInterest ss ns 7 | 8 | collectFields :: Int -> [Int] -> [String] -> [String] 9 | collectFields _ _ [] = [] 10 | collectFields idx fis (s:ss) | idx `elem` fis = s : collectFields (idx+1) fis ss 11 | collectFields idx fis (s:ss) | otherwise = collectFields (idx+1) fis ss 12 | 13 | testDataList n = replicate n "String!" 14 | testDataIndexes n = [0..n-1] 15 | 16 | iterestFunc n = takeInterest (testDataList n) (testDataIndexes n) 17 | collectFunc n = collectFields 0 (testDataIndexes n) (testDataList n) 18 | 19 | main = defaultMain [ 20 | bench "takeInterest 10" $ whnf iterestFunc 10 21 | , bench "collectFields 10" $ whnf collectFunc 10 22 | 23 | , bench "takeInterest 100" $ whnf iterestFunc 100 24 | , bench "collectFields 100" $ whnf collectFunc 100 25 | 26 | , bench "takeInterest 1000" $ whnf iterestFunc 1000 27 | , bench "collectFields 1000" $ whnf collectFunc 1000 28 | 29 | , bench "takeInterest 10000" $ whnf iterestFunc 10000 30 | , bench "collectFields 10000" $ whnf collectFunc 10000 31 | 32 | , bench "takeInterest 50000" $ whnf iterestFunc 50000 33 | , bench "collectFields 50000" $ whnf collectFunc 50000 34 | ] 35 | 36 | {- 37 | Benchmark resuts (means): 38 | Items takeInterest collectFields Percent 39 | 10 17.33 36.84 52.9 40 | 100 20.58 36.84 44.1 41 | 1000 21.67 37.92 42.8 42 | 10000 21.13 36.84 42.6 43 | 50000 21.67 37.92 42.8 44 | -} -------------------------------------------------------------------------------- /Tests/LookAndSay.hs: -------------------------------------------------------------------------------- 1 | module Main where 2 | 3 | import Data.List as L 4 | import Data.List.Split 5 | 6 | las :: String -> String 7 | las = concatMap (concat.map say.group) . splitOn ", " 8 | where 9 | say ss = show (length ss) ++ [head ss] 10 | 11 | lookAndSay :: [String] 12 | lookAndSay = iterate las "1" -------------------------------------------------------------------------------- /Tests/Maybe.hs: -------------------------------------------------------------------------------- 1 | module Main where 2 | 3 | import qualified Data.Map as M 4 | 5 | phonebook :: [(String, String)] 6 | phonebook = 7 | [ ("Bob", "01788 665242") 8 | , ("Fred", "01624 556442") 9 | , ("Alice", "01889 985333") 10 | , ("Jane", "01732 187565") ] 11 | 12 | type PhoneMap = M.Map String String 13 | 14 | phoneMap :: PhoneMap 15 | phoneMap = M.fromList phonebook 16 | 17 | 18 | getPhone :: String -> Maybe String 19 | getPhone name = lookup name phonebook 20 | 21 | printPhone :: Maybe String -> IO () 22 | printPhone Nothing = putStrLn "Not found." 23 | printPhone (Just phone) = putStrLn phone 24 | 25 | evalPhone :: String -> IO () 26 | evalPhone name = (printPhone . getPhone) name 27 | showPhone :: String -> IO () 28 | 29 | showPhone name = printPhone $ getPhone name 30 | 31 | addPhone n p = M.insert n p phoneMap 32 | updatePhone n p = M.update (\_ -> Just p) n phoneMap 33 | 34 | main' = printPhone . getPhone $ "Alice" 35 | main'' = printPhone (getPhone "Alice") 36 | main''2 = printPhone $ getPhone "Alice" 37 | main''3 = printPhone $ getPhone $ "Alice" 38 | 39 | main''' = do 40 | putStr "Enter name: " 41 | name <- getLine 42 | printPhone (getPhone name) 43 | 44 | 45 | main'''' = do 46 | putStr "Enter name: " 47 | name <- getLine 48 | let phone = getPhone name 49 | printPhone phone -------------------------------------------------------------------------------- /Tests/ModuleAbstraction/Main.hs: -------------------------------------------------------------------------------- 1 | module Main where 2 | import PathFind 3 | 4 | f a b c = a (findPath dijkstra b) c -------------------------------------------------------------------------------- /Tests/ModuleAbstraction/PathFind.hs: -------------------------------------------------------------------------------- 1 | module PathFind (findPath, dijkstra, aStar) where 2 | 3 | import qualified PathFind.Dijkstra as D 4 | import qualified PathFind.AStar as A 5 | 6 | data FindPathAlgorithm = Dijkstra | AStar 7 | 8 | findPath Dijkstra = D.findPath 9 | findPath AStar = A.findPath 10 | 11 | dijkstra = Dijkstra 12 | aStar = AStar -------------------------------------------------------------------------------- /Tests/ModuleAbstraction/PathFind/AStar.hs: -------------------------------------------------------------------------------- 1 | module PathFind.AStar (findPath) where 2 | 3 | findPath = undefined -------------------------------------------------------------------------------- /Tests/ModuleAbstraction/PathFind/Dijkstra.hs: -------------------------------------------------------------------------------- 1 | module PathFind.Dijkstra (findPath) where 2 | 3 | findPath = undefined -------------------------------------------------------------------------------- /Tests/MonadAbstraction/Language.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE UndecidableInstances, 2 | FunctionalDependencies, 3 | MultiParamTypeClasses, 4 | FlexibleInstances #-} 5 | 6 | module Language where 7 | 8 | import qualified Data.ConfigFile as CF 9 | import qualified Control.Monad.Reader as R 10 | import qualified Control.Monad.Writer as W 11 | import qualified Control.Monad.State as S 12 | import Data.Either.Utils 13 | 14 | newtype Configuration = Configuration CF.ConfigParser 15 | 16 | {- 17 | 18 | data Section = Section String 19 | data Option = Option String 20 | data Cfg = Cfg String String 21 | 22 | sect = Section 23 | opt = Option 24 | 25 | (Section s) <| (Option o) = Cfg s o 26 | 27 | getSect (Cfg s _) = s 28 | getOpt (Cfg _ o) = o 29 | 30 | type CfgEvaluator m a = Cfg -> m Configuration a 31 | 32 | getOption (Configuration cp) cfg = forceEither $ CF.get cp (getSect cfg) (getOpt cfg) 33 | 34 | option cfg = do 35 | cp <- R.ask 36 | return $ getOption cp cfg 37 | 38 | intOption = option :: CfgEvaluator Int 39 | strOption = option :: CfgEvaluator String 40 | 41 | evaluate cfg def = runMonad def cfg 42 | 43 | -} 44 | 45 | intOption = undefined 46 | 47 | 48 | loadConfiguration fileName = do 49 | conf <- CF.readfile CF.emptyCP fileName 50 | let cp = forceEither conf 51 | return ( Configuration cp {CF.optionxform = id, CF.accessfunc = CF.interpolatingAccess 10} ) 52 | 53 | 54 | class (Monad m) => Abstract d m | m -> d where 55 | runAbstract :: m d -> String -> m a 56 | 57 | 58 | instance Abstract 59 | evaluate def opt = do 60 | cfg <- loadConfiguration opt 61 | return $ R.runReader def cfg 62 | 63 | 64 | instance (Error e, Monad m, MonadTask a m) => MonadTask a (ErrorT e m) where 65 | exit = lift exit 66 | yield = lift yield 67 | fork = lift . fork . runErrorT 68 | watch = lift . watch 69 | signal = lift . signal 70 | 71 | 72 | screenDef = do 73 | sw <- intOption "screenWidth" 74 | sh <- intOption "screenHeight" 75 | cd <- intOption "colorDepth" 76 | return (sw, sh, cd) 77 | 78 | main = do 79 | screenOpts <- runAbstract screenDef "Options.cfg" 80 | 81 | pretty <- R.runWriter (runAbstract screenDef "") screenOpts 82 | putStrLn pretty 83 | 84 | return () 85 | -------------------------------------------------------------------------------- /Tests/MonadAbstraction/StateMonad.hs: -------------------------------------------------------------------------------- 1 | module StateMonad where 2 | 3 | -------------------------------------------------------------------------------- /Tests/Person.xml: -------------------------------------------------------------------------------- 1 | 2 |", "