├── CSharpMonad
├── lib
│ └── Monad.dll
├── project.lock.json
├── src
│ ├── IAppendable.cs
│ ├── utility
│ │ ├── Lam.da.cs
│ │ ├── Unit.cs
│ │ └── Memoize.cs
│ ├── parsec
│ │ ├── expr
│ │ │ ├── Assoc.cs
│ │ │ ├── OperatorTable.cs
│ │ │ └── Operator.cs
│ │ ├── ParserException.cs
│ │ ├── Empty.cs
│ │ ├── language
│ │ │ ├── HaskellDef.cs
│ │ │ ├── HaskellStyle.cs
│ │ │ ├── Haskell98Def.cs
│ │ │ ├── JavaStyle.cs
│ │ │ └── EmptyDef.cs
│ │ ├── ParserChar.cs
│ │ ├── token
│ │ │ ├── bracketing
│ │ │ │ └── Bracketing.cs
│ │ │ ├── ops
│ │ │ │ └── Ops.cs
│ │ │ ├── strings
│ │ │ │ └── Strings.cs
│ │ │ ├── idents
│ │ │ │ └── Idents.cs
│ │ │ ├── LanguageDef.cs
│ │ │ ├── TokenParser.cs
│ │ │ ├── chars
│ │ │ │ └── Chars.cs
│ │ │ ├── TokenTypes.cs
│ │ │ └── TokenParsers.cs
│ │ ├── ParserError.cs
│ │ ├── SrcLoc.cs
│ │ ├── ParserResult.cs
│ │ └── Parser.cs
│ ├── ext
│ │ ├── ObjectExt.cs
│ │ ├── ImmutableListExt.cs
│ │ ├── TupleExt.cs
│ │ └── EnumerableExt.cs
│ ├── option-lazy
│ │ ├── Nothing.cs
│ │ └── Just.cs
│ ├── option-strict
│ │ ├── Nothing.cs
│ │ └── Just.cs
│ ├── Reader.cs
│ ├── State.cs
│ ├── Writer.cs
│ └── RWS.cs
├── CSharpMonad.sln
├── Properties
│ └── AssemblyInfo.cs
├── CSharpMonad.xproj
├── project.json
└── CSharpMonad.csproj
├── .nuget
└── packages.config
├── CSharpMonad.UnitTests
├── packages.config
├── Properties
│ └── AssemblyInfo.cs
├── src
│ ├── MemoizationTests.cs
│ ├── ImmutableListTests.cs
│ ├── WriterTests.cs
│ ├── OptionTests.cs
│ ├── ReaderWriterStateTests.cs
│ ├── IOTests.cs
│ ├── Combined.cs
│ ├── ReaderTests.cs
│ ├── ExprParsers.cs
│ ├── StateTests.cs
│ ├── EitherTests.cs
│ └── TryTests.cs
└── CSharpMonad.UnitTests.csproj
├── LICENSE.md
├── CSharpMonad.sln
├── .gitattributes
└── .gitignore
/CSharpMonad/lib/Monad.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/louthy/csharp-monad/HEAD/CSharpMonad/lib/Monad.dll
--------------------------------------------------------------------------------
/.nuget/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/CSharpMonad/project.lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "locked": false,
3 | "version": 1,
4 | "targets": {
5 | ".NETPortable,Version=v4.5,Profile=Profile7": {}
6 | },
7 | "libraries": {},
8 | "projectFileDependencyGroups": {
9 | "": [],
10 | ".NETPortable,Version=v4.5,Profile=Profile7": []
11 | }
12 | }
--------------------------------------------------------------------------------
/CSharpMonad/src/IAppendable.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace Monad
3 | {
4 | ///
5 | /// Used to append/combine the current object and the one provided.
6 | /// This is used to support the operator+ overload on the monad types
7 | ///
8 | ///
9 | public interface IAppendable
10 | {
11 | T Append(T rhs);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/CSharpMonad.UnitTests/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/CSharpMonad/CSharpMonad.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.25420.1
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "CSharpMonad", "CSharpMonad.xproj", "{C0855756-19E8-4701-8980-4210040B5B5B}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {C0855756-19E8-4701-8980-4210040B5B5B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {C0855756-19E8-4701-8980-4210040B5B5B}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {C0855756-19E8-4701-8980-4210040B5B5B}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {C0855756-19E8-4701-8980-4210040B5B5B}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/CSharpMonad/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 |
3 | // General Information about an assembly is controlled through the following
4 | // set of attributes. Change these attribute values to modify the information
5 | // associated with an assembly.
6 | [assembly: AssemblyTitle("Monad")]
7 | [assembly: AssemblyDescription("Monad library")]
8 | [assembly: AssemblyConfiguration("")]
9 | [assembly: AssemblyCompany("")]
10 | [assembly: AssemblyProduct("Monad")]
11 | [assembly: AssemblyCopyright("Copyright © Paul Louth 2014 - MIT License")]
12 | [assembly: AssemblyTrademark("")]
13 | [assembly: AssemblyCulture("")]
14 |
15 | // Version information for an assembly consists of the following four values:
16 | //
17 | // Major Version
18 | // Minor Version
19 | // Build Number
20 | // Revision
21 | //
22 | // You can specify all the values or you can default the Build and Revision Numbers
23 | // by using the '*' as shown below:
24 | // [assembly: AssemblyVersion("1.0.*")]
25 | [assembly: AssemblyVersion("1.0.0.0")]
26 | [assembly: AssemblyFileVersion("1.0.0.0")]
27 |
--------------------------------------------------------------------------------
/CSharpMonad/CSharpMonad.xproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 14.0
5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
6 |
7 |
8 |
9 | c0855756-19e8-4701-8980-4210040b5b5b
10 | CSharpMonad
11 | .\obj
12 | .\bin\
13 |
14 |
15 |
16 | 2.0
17 |
18 |
19 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016-2019 Paul Louth
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/CSharpMonad/src/utility/Lam.da.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Monad.Utility
4 | {
5 | ///
6 | /// Type inference helper
7 | ///
8 | public static class Lam
9 | {
10 | public static Func da(Func fn)
11 | {
12 | if (fn == null) throw new ArgumentNullException("fn");
13 | return fn;
14 | }
15 |
16 | public static Func da(Func fn)
17 | {
18 | if (fn == null) throw new ArgumentNullException("fn");
19 | return fn;
20 | }
21 |
22 | public static Func da(Func fn)
23 | {
24 | if (fn == null) throw new ArgumentNullException("fn");
25 | return fn;
26 | }
27 |
28 | public static Func da(Func fn)
29 | {
30 | if (fn == null) throw new ArgumentNullException("fn");
31 | return fn;
32 | }
33 |
34 | public static Func da(Func fn)
35 | {
36 | if (fn == null) throw new ArgumentNullException("fn");
37 | return fn;
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/CSharpMonad/src/parsec/expr/Assoc.cs:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////////////
2 | // The MIT License (MIT)
3 | //
4 | // Copyright (c) 2014 Paul Louth
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in all
14 | // copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | // SOFTWARE.
23 | //
24 |
25 | using System;
26 |
27 | namespace Monad.Parsec.Expr
28 | {
29 | public enum Assoc
30 | {
31 | None,
32 | Left,
33 | Right
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/CSharpMonad.UnitTests/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Monad.UnitTests")]
9 | [assembly: AssemblyDescription("Monad library unit tests")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("Monad.UnitTests")]
13 | [assembly: AssemblyCopyright("Copyright © Paul Louth 2014 - MIT License")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("64b47c63-9311-4431-bd6f-dbc8965bac9e")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/CSharpMonad/src/parsec/ParserException.cs:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////////////
2 | // The MIT License (MIT)
3 | //
4 | // Copyright (c) 2014 Paul Louth
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in all
14 | // copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | // SOFTWARE.
23 | //
24 |
25 | using System;
26 | using System.Collections.Generic;
27 | using System.Linq;
28 | using System.Text;
29 |
30 | namespace Monad.Parsec
31 | {
32 | public class ParserException : Exception
33 | {
34 | public ParserException(string msg)
35 | :
36 | base(msg)
37 | {
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/CSharpMonad/src/parsec/Empty.cs:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////////////
2 | // The MIT License (MIT)
3 | //
4 | // Copyright (c) 2014 Paul Louth
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in all
14 | // copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | // SOFTWARE.
23 | //
24 |
25 | using System;
26 | using System.Collections.Generic;
27 | using Monad.Utility;
28 |
29 | namespace Monad.Parsec
30 | {
31 | public static class Empty
32 | {
33 | public static IEnumerable>> Return()
34 | {
35 | return new Tuple>[0];
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/CSharpMonad/src/ext/ObjectExt.cs:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////////////
2 | // The MIT License (MIT)
3 | //
4 | // Copyright (c) 2014 Paul Louth
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in all
14 | // copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | // SOFTWARE.
23 | //
24 |
25 | using Monad.Utility;
26 | using System;
27 |
28 | namespace Monad
29 | {
30 | public static class ObjectExt
31 | {
32 | public static ImmutableList Cons(this T x, ImmutableList xs)
33 | {
34 | if (xs == null) throw new ArgumentNullException("xs");
35 | return xs.InsertAtHead(x);
36 | }
37 |
38 | public static ImmutableList Cons(this T x)
39 | {
40 | return new ImmutableList(new T[1] { x });
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/CSharpMonad/src/parsec/language/HaskellDef.cs:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////////////
2 | // The MIT License (MIT)
3 | //
4 | // Copyright (c) 2014 Paul Louth
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in all
14 | // copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | // SOFTWARE.
23 |
24 | using System.Linq;
25 |
26 | namespace Monad.Parsec.Language
27 | {
28 | public class HaskellDef : Haskell98Def
29 | {
30 | public HaskellDef()
31 | {
32 | IdentLetter = IdentLetter.Or(Prim.Character('#'));
33 | ReservedNames = Enumerable.Concat(
34 | ReservedNames,
35 | new string[] { "foreign","import","export","primitive"
36 | ,"_ccall_","_casm_"
37 | ,"forall"
38 | });
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/CSharpMonad/src/parsec/language/HaskellStyle.cs:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////////////
2 | // The MIT License (MIT)
3 | //
4 | // Copyright (c) 2014 Paul Louth
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in all
14 | // copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | // SOFTWARE.
23 | //
24 |
25 | namespace Monad.Parsec.Language
26 | {
27 | public class HaskellStyle : EmptyDef
28 | {
29 | public HaskellStyle()
30 | {
31 | CommentStart = "{-";
32 | CommentEnd = "-}";
33 | CommentLine = "--";
34 | NestedComments = true;
35 | IdentStart = Prim.Letter();
36 | IdentLetter = Prim.LetterOrDigit().Or(Prim.Character('_').Or(Prim.Character('\'')));
37 | OpStart = OpLetter = Prim.OneOf(":!#$%&*+./<=>?@\\^|-~");
38 | ReservedOpNames = new string[0];
39 | ReservedNames = new string[0];
40 | CaseSensitive = true;
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/CSharpMonad/src/parsec/ParserChar.cs:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////////////
2 | // The MIT License (MIT)
3 | //
4 | // Copyright (c) 2014 Paul Louth
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in all
14 | // copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | // SOFTWARE.
23 | //
24 |
25 | namespace Monad.Parsec
26 | {
27 | public struct ParserChar
28 | {
29 | public readonly char Value;
30 | public readonly SrcLoc Location;
31 |
32 | public ParserChar(char c, SrcLoc location = null)
33 | {
34 | Value = c;
35 | Location = location == null
36 | ? SrcLoc.Null
37 | : location;
38 | }
39 |
40 | public override string ToString()
41 | {
42 | return Value.ToString();
43 | }
44 |
45 | public override int GetHashCode()
46 | {
47 | return Location == null ? Value.GetHashCode() : Location.GetHashCode();
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/CSharpMonad.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.24720.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpMonad.UnitTests", "CSharpMonad.UnitTests\CSharpMonad.UnitTests.csproj", "{496943F4-17B4-41CB-8013-5499543E3DA0}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{51C6DCA8-5534-4D6B-B7A1-FCA877421A47}"
9 | ProjectSection(SolutionItems) = preProject
10 | LICENSE.md = LICENSE.md
11 | README.md = README.md
12 | EndProjectSection
13 | EndProject
14 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{C753F430-F758-4309-AFE5-87B825D242FD}"
15 | ProjectSection(SolutionItems) = preProject
16 | .nuget\packages.config = .nuget\packages.config
17 | EndProjectSection
18 | EndProject
19 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpMonad", "CSharpMonad\CSharpMonad.csproj", "{254ABD61-BEDB-4478-9708-606E85310FE0}"
20 | EndProject
21 | Global
22 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
23 | Debug|Any CPU = Debug|Any CPU
24 | Release|Any CPU = Release|Any CPU
25 | EndGlobalSection
26 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
27 | {496943F4-17B4-41CB-8013-5499543E3DA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
28 | {496943F4-17B4-41CB-8013-5499543E3DA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
29 | {496943F4-17B4-41CB-8013-5499543E3DA0}.Release|Any CPU.ActiveCfg = Release|Any CPU
30 | {496943F4-17B4-41CB-8013-5499543E3DA0}.Release|Any CPU.Build.0 = Release|Any CPU
31 | {254ABD61-BEDB-4478-9708-606E85310FE0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
32 | {254ABD61-BEDB-4478-9708-606E85310FE0}.Debug|Any CPU.Build.0 = Debug|Any CPU
33 | {254ABD61-BEDB-4478-9708-606E85310FE0}.Release|Any CPU.ActiveCfg = Release|Any CPU
34 | {254ABD61-BEDB-4478-9708-606E85310FE0}.Release|Any CPU.Build.0 = Release|Any CPU
35 | EndGlobalSection
36 | GlobalSection(SolutionProperties) = preSolution
37 | HideSolutionNode = FALSE
38 | EndGlobalSection
39 | EndGlobal
40 |
--------------------------------------------------------------------------------
/CSharpMonad/src/parsec/language/Haskell98Def.cs:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////////////
2 | // The MIT License (MIT)
3 | //
4 | // Copyright (c) 2014 Paul Louth
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in all
14 | // copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | // SOFTWARE.
23 | //
24 |
25 | namespace Monad.Parsec.Language
26 | {
27 | public class Haskell98Def : HaskellStyle
28 | {
29 | public Haskell98Def()
30 | {
31 | ReservedOpNames = new string[] {"::","..","=","\\","|","<-","->","@","~","=>"};
32 | ReservedNames = new string[] {"let","in","case","of","if","then","else",
33 | "data","type",
34 | "class","default","deriving","do","import",
35 | "infix","infixl","infixr","instance","module",
36 | "newtype","where",
37 | "primitive"
38 | // "as","qualified","hiding"
39 | };
40 |
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/CSharpMonad/src/parsec/language/JavaStyle.cs:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////////////
2 | // The MIT License (MIT)
3 | //
4 | // Copyright (c) 2014 Paul Louth
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in all
14 | // copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | // SOFTWARE.
23 | //
24 |
25 | namespace Monad.Parsec.Language
26 | {
27 | ///
28 | /// This is a minimal token definition for Java style languages. It
29 | /// defines the style of comments, valid identifiers and case
30 | /// sensitivity. It does not define any reserved words or operators.
31 | ///
32 | public class JavaStyle : EmptyDef
33 | {
34 | public JavaStyle()
35 | {
36 | CommentStart = "/*";
37 | CommentEnd = "*/";
38 | CommentLine = "//";
39 | NestedComments = true;
40 | IdentStart = Prim.Letter();
41 | IdentLetter = Prim.LetterOrDigit().Or(Prim.Character('_').Or(Prim.Character('\'')));
42 | ReservedOpNames = new string[0];
43 | ReservedNames = new string[0];
44 | CaseSensitive = true;
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/CSharpMonad.UnitTests/src/MemoizationTests.cs:
--------------------------------------------------------------------------------
1 | using Xunit;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace Monad.UnitTests
9 | {
10 | public class MemoizationTests
11 | {
12 | int breakIt = 0;
13 |
14 | [Fact]
15 | public void MemoizationTest1()
16 | {
17 | var mon = (from one in One()
18 | from two in Two()
19 | from thr in Three()
20 | select one + two + thr)
21 | .Memo();
22 |
23 | var res = mon();
24 | Assert.True(res == 6);
25 | breakIt++;
26 |
27 | res = mon();
28 | Assert.True(res == 6);
29 | }
30 |
31 | public Monad One()
32 | {
33 | return () => 1 + breakIt;
34 | }
35 |
36 | public Monad Two()
37 | {
38 | return () => 2 + breakIt;
39 | }
40 |
41 | public Monad Three()
42 | {
43 | return () => 3 + breakIt;
44 | }
45 | }
46 |
47 | public delegate T Monad();
48 |
49 | public static class TestMonadExt
50 | {
51 | public static Monad Select(this Monad self, Func map)
52 | {
53 | return () =>
54 | {
55 | var resT = self();
56 |
57 | var resU = map(resT);
58 |
59 | return resU;
60 | };
61 | }
62 |
63 | public static Monad SelectMany(
64 | this Monad self,
65 | Func> select,
66 | Func project
67 | )
68 | {
69 | return () =>
70 | {
71 | var resT = self();
72 | var resU = select(resT)();
73 | var resV = project(resT, resU);
74 |
75 | return resV;
76 | };
77 | }
78 |
79 | ///
80 | /// Memoize the result
81 | ///
82 | public static Func Memo(this Monad self)
83 | {
84 | var res = self();
85 | return () => res;
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/CSharpMonad/src/utility/Unit.cs:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////////////
2 | // The MIT License (MIT)
3 | //
4 | // Copyright (c) 2014 Paul Louth
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in all
14 | // copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | // SOFTWARE.
23 | //
24 |
25 | using System;
26 |
27 | namespace Monad.Utility
28 | {
29 | ///
30 | /// A type with only one value, itself.
31 | /// This is the functional world's equivalent of Void.
32 | ///
33 | public struct Unit
34 | {
35 | ///
36 | /// Use a singleton so that ref equality works and to reduce any unnecessary
37 | /// thrashing of the GC from creating an object which is always the same.
38 | ///
39 | public static readonly Unit Default = new Unit();
40 |
41 | ///
42 | /// Performs an action which instead of returning void will return Unit
43 | ///
44 | ///
45 | ///
46 | public static Unit Return(Action action)
47 | {
48 | if (action == null) throw new ArgumentNullException("action");
49 |
50 | action();
51 | return Default;
52 | }
53 | }
54 | }
--------------------------------------------------------------------------------
/CSharpMonad/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "csharp-monad",
3 | "title": "csharp-monad",
4 | "version": "1.0.0-*",
5 | "authors": [ "Paul Louth" ],
6 | "description": "C# Monad Library",
7 | "packOptions": {
8 | "id": "csharp-monad",
9 | "title": "C# Monad Library",
10 | "owners": [ "paullouth" ],
11 | "tags": [ "C#", "Functional", "Monad", "Option", "Either", "Reader", "Writer", "State" ],
12 | "iconUrl": "https://camo.githubusercontent.com/08525ae465a9061150679d871731e77b399c2a94/687474703a2f2f7777772e34666f75722e6f72672f696d616765732f6c616e672d6578742d6c6f676f2e706e67",
13 | "summary": "A C# library of monads and a full set of parser combinators based on the Haskell Parsec library.\nEither \nEitherStrict \nIO \nOption \nOptionStrict \nParser \nReader \nRWS - Combined Reader/Writer/State\nState \nTry\nWriter",
14 | "releaseNotes": "",
15 | "projectUrl": "https://github.com/louthy/csharp-monad",
16 | "licenseUrl": "https://github.com/louthy/csharp-monad/blob/master/LICENSE.md"
17 | },
18 | "copyright": "Copyright (c) Paul Louth",
19 | "configurations": {
20 | "Debug": {
21 | "buildOptions": {
22 | "define": [ "DEBUG", "TRACE" ],
23 | "compile": "*.cs"
24 | }
25 | },
26 | "Release": {
27 | "buildOptions": {
28 | "define": [ "RELEASE", "TRACE" ],
29 | "optimize": true,
30 | "compile": "*.cs"
31 | }
32 | }
33 | },
34 | "dependencies": {
35 | },
36 | "frameworks": {
37 | "net45": {
38 | "frameworkAssemblies": {
39 | "System.Core": "4.0.0.0"
40 | },
41 | "dependencies": {
42 | }
43 | },
44 | "net46": {
45 | "frameworkAssemblies": {
46 | "System.Core": "4.0.0.0"
47 | },
48 | "dependencies": {
49 | }
50 | },
51 | "netcoreapp10": {
52 | "dependencies": {
53 | "System.Runtime.Extensions": "4.1.0",
54 | "System.Collections": "4.0.11",
55 | "System.Reflection": "4.1.0",
56 | "System.Linq": "4.1.0"
57 | }
58 | },
59 | "netstandard13": {
60 | "dependencies": {
61 | "System.Runtime.Extensions": "4.1.0",
62 | "System.Collections": "4.0.11",
63 | "System.Reflection": "4.1.0",
64 | "System.Linq": "4.1.0"
65 | }
66 | }
67 | },
68 | "buildOptions": {
69 | "optimize": true
70 | }
71 | }
--------------------------------------------------------------------------------
/CSharpMonad/src/parsec/language/EmptyDef.cs:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////////////
2 | // The MIT License (MIT)
3 | //
4 | // Copyright (c) 2014 Paul Louth
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in all
14 | // copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | // SOFTWARE.
23 | //
24 |
25 | using Monad.Parsec.Token;
26 |
27 | namespace Monad.Parsec.Language
28 | {
29 | ///
30 | /// This is the most minimal token definition. It is recommended to use
31 | /// this definition as the basis for other definitions. EmptyDef has
32 | /// no reserved names or operators, is case sensitive and doesn't accept
33 | /// comments, identifiers or operators
34 | ///
35 | public class EmptyDef : LanguageDef
36 | {
37 | public EmptyDef()
38 | {
39 | CommentStart = "";
40 | CommentEnd = "";
41 | CommentLine = "";
42 | NestedComments = true;
43 | IdentStart = Prim.Letter().Or( Prim.Character('_') );
44 | IdentLetter = Prim.LetterOrDigit().Or(Prim.Character('_').Or(Prim.Character('\'')));
45 | OpStart = OpLetter = Prim.OneOf(":!#$%&*+./<=>?@\\^|-~");
46 | ReservedOpNames = new string[0];
47 | ReservedNames = new string[0];
48 | CaseSensitive = true;
49 |
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/CSharpMonad/src/option-lazy/Nothing.cs:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////////////
2 | // The MIT License (MIT)
3 | //
4 | // Copyright (c) 2014 Paul Louth
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in all
14 | // copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | // SOFTWARE.
23 | //
24 |
25 | using System;
26 |
27 | namespace Monad
28 | {
29 | ///
30 | /// Nothing case of the Option monad
31 | ///
32 | public class NothingResult : OptionResult
33 | {
34 | internal static OptionResult Default = new NothingResult();
35 |
36 | public override string ToString()
37 | {
38 | return "[Nothing]";
39 | }
40 |
41 | public override T Value
42 | {
43 | get
44 | {
45 | throw new InvalidOperationException("Option.Nothing has no value");
46 | }
47 | }
48 |
49 | public override bool HasValue
50 | {
51 | get
52 | {
53 | return false;
54 | }
55 | }
56 |
57 | ///
58 | /// Monadic append
59 | /// If the lhs or rhs are in a Nothing state then Nothing propagates
60 | ///
61 | public override OptionResult Mappend(OptionResult rhs)
62 | {
63 | if (rhs == null) throw new ArgumentNullException("rhs");
64 | return this;
65 | }
66 | }
67 | }
--------------------------------------------------------------------------------
/CSharpMonad/src/parsec/token/bracketing/Bracketing.cs:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////////////
2 | // The MIT License (MIT)
3 | //
4 | // Copyright (c) 2014 Paul Louth
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in all
14 | // copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | // SOFTWARE.
23 | //
24 |
25 | namespace Monad.Parsec.Token.Bracketing
26 | {
27 | public class Parens : Parser
28 | {
29 | public Parens(Parser betweenParser)
30 | :
31 | base( inp => Prim.Between( Tok.Symbol("("), Tok.Symbol(")"), betweenParser )
32 | .Parse(inp) )
33 | { }
34 | }
35 | public class Braces : Parser
36 | {
37 | public Braces(Parser betweenParser)
38 | :
39 | base(inp => Prim.Between(Tok.Symbol("{"), Tok.Symbol("}"), betweenParser)
40 | .Parse(inp))
41 | { }
42 | }
43 | public class Angles : Parser
44 | {
45 | public Angles(Parser betweenParser)
46 | :
47 | base(inp => Prim.Between(Tok.Symbol("<"), Tok.Symbol(">"), betweenParser)
48 | .Parse(inp))
49 | { }
50 | }
51 | public class Brackets : Parser
52 | {
53 | public Brackets(Parser betweenParser)
54 | :
55 | base(inp => Prim.Between(Tok.Symbol("["), Tok.Symbol("]"), betweenParser)
56 | .Parse(inp))
57 | { }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/CSharpMonad/src/parsec/ParserError.cs:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////////////
2 | // The MIT License (MIT)
3 | //
4 | // Copyright (c) 2014 Paul Louth
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in all
14 | // copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | // SOFTWARE.
23 | //
24 |
25 | using System;
26 | using System.Collections.Generic;
27 | using System.Linq;
28 | using System.Text;
29 | using Monad.Utility;
30 |
31 | namespace Monad.Parsec
32 | {
33 | public class ParserError
34 | {
35 | public readonly string Message;
36 | public readonly string Expected;
37 | public readonly ImmutableList Input;
38 | public readonly SrcLoc Location;
39 |
40 | public ParserError(string expected, ImmutableList input, string message = "")
41 | {
42 | Message = message;
43 | Expected = expected;
44 | Input = input;
45 | if (input.IsEmpty)
46 | {
47 | Location = SrcLoc.EndOfSource;
48 | }
49 | else
50 | {
51 | Location = input.Head().Location;
52 | }
53 | }
54 |
55 | public static ParserError Create(string expected, ImmutableList input, string message = "")
56 | {
57 | return new ParserError(expected, input, message);
58 | }
59 |
60 | public static ParserError Create(char expected, ImmutableList input, string message = "")
61 | {
62 | return new ParserError(expected.ToString(), input, message);
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/CSharpMonad.UnitTests/src/ImmutableListTests.cs:
--------------------------------------------------------------------------------
1 | using Monad.Parsec;
2 | using Xunit;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 | using Monad.Utility;
9 |
10 |
11 | namespace Monad.UnitTests
12 | {
13 | public class ImmutableListTests
14 | {
15 | [Fact]
16 | public void EnumeratorTest1()
17 | {
18 | var list1 = new ImmutableList(new int[] { 0, 1, 2 });
19 |
20 | int index = 0;
21 | foreach (var item in list1)
22 | {
23 | Assert.True(item == index);
24 | index++;
25 | }
26 | Assert.True(index == 3);
27 | }
28 |
29 | [Fact]
30 | public void EnumeratorTest2()
31 | {
32 | var list1 = new ImmutableList(new int[] { 0, 1, 2 });
33 | var list2 = new ImmutableList(new int[] { 3, 4, 5 });
34 |
35 | var list = list1.Concat(list2);
36 |
37 | int index = 0;
38 | foreach (var item in list)
39 | {
40 | Assert.True(item == index);
41 | index++;
42 | }
43 |
44 | Assert.True(index == 6);
45 | }
46 |
47 | [Fact]
48 | public void EnumeratorTest3()
49 | {
50 | var list1 = new ImmutableList(new int[] { 1, 2, 3 });
51 | var list2 = new ImmutableList(new int[] { 4, 5, 6 });
52 |
53 | var list = 0.Cons( list1.Concat(list2) );
54 |
55 | int index = 0;
56 | foreach (var item in list)
57 | {
58 | Assert.True(item == index);
59 | index++;
60 | }
61 |
62 | Assert.True(index == 7);
63 | }
64 |
65 | [Fact]
66 | public void EnumeratorLengthTest1()
67 | {
68 | var list1 = new ImmutableList(new int[] { 0, 1, 2 });
69 | var list2 = new ImmutableList(new int[] { 3, 4, 5 });
70 |
71 | var list = list1.Concat(list2);
72 |
73 | Assert.True(list.Length == 6);
74 |
75 | list = list.Tail();
76 | Assert.True(list.Length == 5);
77 |
78 | list = list.Tail();
79 | list = list.Tail();
80 | list = list.Tail();
81 | list = list.Tail();
82 |
83 | Assert.True(list.Length == 1);
84 | Assert.True(list.IsAlmostEmpty);
85 |
86 | list = list.Tail();
87 | Assert.True(list.IsEmpty);
88 |
89 | Assert.Throws(() => list.Tail());
90 | }
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/CSharpMonad/src/parsec/expr/OperatorTable.cs:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////////////
2 | // The MIT License (MIT)
3 | //
4 | // Copyright (c) 2014 Paul Louth
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in all
14 | // copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | // SOFTWARE.
23 | //
24 |
25 | using System;
26 | using System.Collections.Generic;
27 | using System.Linq;
28 | using System.Text;
29 |
30 | namespace Monad.Parsec.Expr
31 | {
32 | public class OperatorTable : IEnumerable>>
33 | {
34 | List>> ops = new List>>();
35 | int current = -1;
36 |
37 | public OperatorTable()
38 | {
39 | }
40 |
41 | public OperatorTable AddRow()
42 | {
43 | current++;
44 | ops.Add(new Operator[0]);
45 | return this;
46 | }
47 |
48 | public OperatorTable Add(Operator op)
49 | {
50 | ops[current] = ops[current].Concat(op.Cons());
51 | return this;
52 | }
53 |
54 | public IEnumerable>> AsImmutableList()
55 | {
56 | return ops;
57 | }
58 |
59 | public IEnumerator>> GetEnumerator()
60 | {
61 | return ((IEnumerable>>)ops).GetEnumerator();
62 | }
63 |
64 | System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
65 | {
66 | return ((IEnumerable>>)ops).GetEnumerator();
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/CSharpMonad/src/parsec/SrcLoc.cs:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////////////
2 | // The MIT License (MIT)
3 | //
4 | // Copyright (c) 2014 Paul Louth
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in all
14 | // copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | // SOFTWARE.
23 | //
24 |
25 | using System;
26 |
27 | namespace Monad.Parsec
28 | {
29 | ///
30 | /// Represents a location in the source
31 | ///
32 | public class SrcLoc
33 | {
34 | private static SrcLoc unit = new SrcLoc(0, 0,"(location:null)");
35 | private static SrcLoc endOfSource = new SrcLoc(0, 0, "(end-of-source)");
36 |
37 | public readonly int Line;
38 | public readonly int Column;
39 |
40 | private SrcLoc(int line, int column, string displayTemplate)
41 | {
42 | Line = line;
43 | Column = column;
44 | }
45 |
46 | public static SrcLoc Return(int line, int column)
47 | {
48 | return new SrcLoc(line, column,"({0},{1})");
49 | }
50 |
51 | public static SrcLoc Null
52 | {
53 | get
54 | {
55 | return unit;
56 | }
57 | }
58 |
59 | public static SrcLoc EndOfSource
60 | {
61 | get
62 | {
63 | return endOfSource;
64 | }
65 | }
66 |
67 | public override string ToString()
68 | {
69 | return String.Format("({0},{1})", Line, Column);
70 | }
71 |
72 | public override int GetHashCode()
73 | {
74 | unchecked
75 | {
76 | return (Line << 16) | Column;
77 | }
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/CSharpMonad.UnitTests/src/WriterTests.cs:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////////////
2 | // The MIT License (MIT)
3 | //
4 | // Copyright (c) 2014 Paul Louth
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in all
14 | // copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | // SOFTWARE.
23 | //
24 |
25 | using System;
26 | using System.Linq;
27 | using Xunit;
28 | using Monad.Utility;
29 | using Monad;
30 |
31 | namespace Monad.UnitTests
32 | {
33 | public class WriterTests
34 | {
35 | [Fact]
36 | public void Binding1()
37 | {
38 | var res = from a in LogNumber(3)
39 | from b in LogNumber(5)
40 | select a * b;
41 |
42 | var memo = res.Memo();
43 |
44 | Assert.True(memo().Value == 15 && memo().Output.Count() == 2);
45 | Assert.True(memo().Output.First() == "Got number: 3");
46 | Assert.True(memo().Output.Skip(1).First() == "Got number: 5");
47 | }
48 |
49 | [Fact]
50 | public void Binding2()
51 | {
52 | var res = from a in LogNumber(3)
53 | from b in LogNumber(5)
54 | from _ in Writer.Tell("Gonna multiply these two")
55 | select a * b;
56 |
57 | var memo = res.Memo();
58 |
59 | Assert.True(memo().Value == 15 && memo().Output.Count() == 3);
60 | Assert.True(memo().Output.First() == "Got number: 3");
61 | Assert.True(memo().Output.Skip(1).First() == "Got number: 5");
62 | Assert.True(memo().Output.Skip(2).First() == "Gonna multiply these two");
63 | }
64 |
65 | private static Writer LogNumber(int num)
66 | {
67 | return () => Writer.Tell(num, "Got number: " + num);
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/CSharpMonad/src/parsec/expr/Operator.cs:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////////////
2 | // The MIT License (MIT)
3 | //
4 | // Copyright (c) 2014 Paul Louth
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in all
14 | // copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | // SOFTWARE.
23 | //
24 |
25 | using System;
26 |
27 | namespace Monad.Parsec.Expr
28 | {
29 | public enum OperatorType
30 | {
31 | None,
32 | Infix,
33 | Postfix,
34 | Prefix
35 | }
36 |
37 | public abstract class Operator
38 | {
39 | public readonly OperatorType Type;
40 | public readonly string Name;
41 |
42 | public Operator(OperatorType type, string name)
43 | {
44 | Type = type;
45 | Name = name;
46 | }
47 | }
48 |
49 | public class Infix : Operator
50 | {
51 | public readonly Assoc Assoc;
52 | public readonly Parser> Parser;
53 |
54 | public Infix(string name, Parser> parser, Assoc assoc)
55 | :
56 | base(OperatorType.Infix, name)
57 | {
58 | Parser = parser;
59 | Assoc = assoc;
60 | }
61 | }
62 |
63 | public class Prefix : Operator
64 | {
65 | public readonly Parser> Parser;
66 |
67 | public Prefix(string name, Parser> parser)
68 | :
69 | base(OperatorType.Prefix, name)
70 | {
71 | Parser = parser;
72 | }
73 | }
74 |
75 | public class Postfix : Operator
76 | {
77 | public readonly Parser> Parser;
78 |
79 | public Postfix(string name, Parser> parser)
80 | :
81 | base(OperatorType.Postfix, name)
82 | {
83 | Parser = parser;
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.sln.docstates
8 |
9 | # Build results
10 |
11 | [Dd]ebug/
12 | [Rr]elease/
13 | x64/
14 | build/
15 | [Bb]in/
16 | [Oo]bj/
17 |
18 | .nuget
19 | packages/
20 |
21 | # MSTest test Results
22 | [Tt]est[Rr]esult*/
23 | [Bb]uild[Ll]og.*
24 |
25 | *_i.c
26 | *_p.c
27 | *.ilk
28 | *.meta
29 | *.obj
30 | *.pch
31 | *.pdb
32 | *.pgc
33 | *.pgd
34 | *.rsp
35 | *.sbr
36 | *.tlb
37 | *.tli
38 | *.tlh
39 | *.tmp
40 | *.tmp_proj
41 | *.log
42 | *.vspscc
43 | *.vssscc
44 | .builds
45 | *.pidb
46 | *.log
47 | *.scc
48 |
49 | # Visual C++ cache files
50 | ipch/
51 | *.aps
52 | *.ncb
53 | *.opensdf
54 | *.sdf
55 | *.cachefile
56 |
57 | # Visual Studio profiler
58 | *.psess
59 | *.vsp
60 | *.vspx
61 |
62 | # Guidance Automation Toolkit
63 | *.gpState
64 |
65 | # ReSharper is a .NET coding add-in
66 | _ReSharper*/
67 | *.[Rr]e[Ss]harper
68 |
69 | # TeamCity is a build add-in
70 | _TeamCity*
71 |
72 | # DotCover is a Code Coverage Tool
73 | *.dotCover
74 |
75 | # NCrunch
76 | *.ncrunch*
77 | .*crunch*.local.xml
78 |
79 | # Installshield output folder
80 | [Ee]xpress/
81 |
82 | # DocProject is a documentation generator add-in
83 | DocProject/buildhelp/
84 | DocProject/Help/*.HxT
85 | DocProject/Help/*.HxC
86 | DocProject/Help/*.hhc
87 | DocProject/Help/*.hhk
88 | DocProject/Help/*.hhp
89 | DocProject/Help/Html2
90 | DocProject/Help/html
91 |
92 | # Click-Once directory
93 | publish/
94 |
95 | # Publish Web Output
96 | *.Publish.xml
97 |
98 | # NuGet Packages Directory
99 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line
100 | #packages/
101 |
102 | # Windows Azure Build Output
103 | csx
104 | *.build.csdef
105 |
106 | # Windows Store app package directory
107 | AppPackages/
108 |
109 | # Others
110 | sql/
111 | *.Cache
112 | ClientBin/
113 | [Ss]tyle[Cc]op.*
114 | ~$*
115 | *~
116 | *.dbmdl
117 | *.[Pp]ublish.xml
118 | *.pfx
119 | *.publishsettings
120 |
121 | # RIA/Silverlight projects
122 | Generated_Code/
123 |
124 | # Backup & report files from converting an old project file to a newer
125 | # Visual Studio version. Backup files are not needed, because we have git ;-)
126 | _UpgradeReport_Files/
127 | Backup*/
128 | UpgradeLog*.XML
129 | UpgradeLog*.htm
130 |
131 | # SQL Server files
132 | App_Data/*.mdf
133 | App_Data/*.ldf
134 |
135 |
136 | #LightSwitch generated files
137 | GeneratedArtifacts/
138 | _Pvt_Extensions/
139 | ModelManifest.xml
140 |
141 | # =========================
142 | # Windows detritus
143 | # =========================
144 |
145 | # Windows image file caches
146 | Thumbs.db
147 | ehthumbs.db
148 |
149 | # Folder config file
150 | Desktop.ini
151 |
152 | # Recycle Bin used on file shares
153 | $RECYCLE.BIN/
154 |
155 | # Mac desktop service store files
156 | .DS_Store
157 | /.vs/config/applicationhost.config
158 | /CSharpMonad/.vs/restore.dg
159 | *.lock.json
160 | /CSharpMonad/.vs/config/applicationhost.config
161 |
--------------------------------------------------------------------------------
/CSharpMonad.UnitTests/src/OptionTests.cs:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////////////
2 | // The MIT License (MIT)
3 | //
4 | // Copyright (c) 2014 Paul Louth
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in all
14 | // copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | // SOFTWARE.
23 | //
24 |
25 | using Xunit;
26 | using System;
27 | using System.Collections.Generic;
28 | using System.Linq;
29 | using System.Text;
30 | using System.Threading.Tasks;
31 | using Monad;
32 | using Monad.Utility;
33 |
34 | namespace Monad.UnitTests
35 | {
36 | public class OptionTests
37 | {
38 | [Fact]
39 | public void TestBinding()
40 | {
41 | Option option = () => 1000.ToOption();
42 | Option option2 = () => 2000.ToOption();
43 |
44 | var result = from o in option
45 | select o;
46 |
47 | Assert.True(result.HasValue() && result.Value() == 1000);
48 | Assert.True(result.Match(Just: () => true, Nothing: () => false)());
49 | Assert.True(result.Match(Just: () => true, Nothing: false)());
50 |
51 | result = from o in option
52 | from o2 in option2
53 | select o2;
54 |
55 | Assert.True(result.HasValue() && result.Value() == 2000);
56 | Assert.True(result.Match(Just: () => true, Nothing: () => false)());
57 | Assert.True(result.Match(Just: () => true, Nothing: false)());
58 |
59 | result = from o in option
60 | from o2 in Nothing()
61 | select o2;
62 |
63 | Assert.True(result.HasValue() == false);
64 | }
65 |
66 | [Fact]
67 | public void TestEquals()
68 | {
69 | OptionStrict option = 1000.ToOptionStrict();
70 | OptionStrict option2 = 1000.ToOptionStrict();
71 |
72 | Assert.True(option == option2);
73 | }
74 |
75 | public Option Nothing()
76 | {
77 | return Option.Nothing();
78 | }
79 | }
80 | }
--------------------------------------------------------------------------------
/CSharpMonad/src/ext/ImmutableListExt.cs:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////////////
2 | // The MIT License (MIT)
3 | //
4 | // Copyright (c) 2014 Paul Louth
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in all
14 | // copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | // SOFTWARE.
23 | //
24 |
25 | using Monad.Parsec;
26 | using Monad.Utility;
27 | using System;
28 |
29 | namespace Monad
30 | {
31 | public static class ImmutableListExt
32 | {
33 | public static bool CanTake(this ImmutableList self, int amount)
34 | {
35 | return self.Length - amount >= 0;
36 | }
37 |
38 | public static string AsString(this ImmutableList self)
39 | {
40 | return String.Concat(self.Select(pc=>pc.Value));
41 | }
42 |
43 | public static T Second(this ImmutableList self)
44 | {
45 | return self.Tail().Head();
46 | }
47 |
48 | ///
49 | /// Foldr
50 | ///
51 | public static U Foldr(this ImmutableList self, Func func, U state)
52 | {
53 | foreach (var item in self)
54 | {
55 | state = func(item, state);
56 | }
57 | return state;
58 | }
59 |
60 | ///
61 | /// Foldr
62 | ///
63 | public static U Foldr(this ImmutableList self, Func func, U state)
64 | {
65 | foreach (var item in self)
66 | {
67 | state = func(state);
68 | }
69 | return state;
70 | }
71 |
72 | ///
73 | /// Foldl
74 | ///
75 | public static U Foldl(this ImmutableList self, Func func, U state)
76 | {
77 | var iter = self.GetReverseEnumerator();
78 | while (iter.MoveNext())
79 | {
80 | state = func(iter.Current, state);
81 | }
82 | return state;
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/CSharpMonad.UnitTests/src/ReaderWriterStateTests.cs:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////////////
2 | // The MIT License (MIT)
3 | //
4 | // Copyright (c) 2014 Paul Louth
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in all
14 | // copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | // SOFTWARE.
23 | //
24 |
25 | using System;
26 | using System.Collections.Generic;
27 | using System.Linq;
28 | using System.Text;
29 | using System.Threading.Tasks;
30 | using Xunit;
31 | using Monad;
32 |
33 | namespace Monad.UnitTests
34 | {
35 | public class ReaderWriterStateTests
36 | {
37 | [Fact]
38 | public void ReaderWriterStateTest1()
39 | {
40 | var world = RWS.Return(0);
41 |
42 | var rws = (from _ in world
43 | from app in RWS.Get()
44 | from env in RWS.Ask()
45 | from x in Value(app.UsersLoggedIn, "Users logged in: " + app.UsersLoggedIn)
46 | from y in Value(100, "System folder: " + env.SystemFolder)
47 | from s in RWS.Put(new App { UsersLoggedIn = 35 })
48 | from t in RWS.Tell("Process complete")
49 | select x * y)
50 | .Memo(new Env(), new App());
51 |
52 | var res = rws();
53 |
54 | Assert.True(res.Value == 3400);
55 | Assert.True(res.State.UsersLoggedIn == 35);
56 | Assert.True(res.Output.Count() == 3);
57 | Assert.True(res.Output.First() == "Users logged in: 34");
58 | Assert.True(res.Output.Skip(1).First() == "System folder: C:/Temp");
59 | Assert.True(res.Output.Skip(2).First() == "Process complete");
60 | }
61 |
62 | public static RWS Value(int val, string log)
63 | {
64 | return (Env r, App s) => RWS.Tell(val, log);
65 | }
66 | }
67 |
68 |
69 | public class App
70 | {
71 | public int UsersLoggedIn = 34;
72 | }
73 |
74 | public class Env
75 | {
76 | public string SystemFolder = "C:/Temp";
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/CSharpMonad/src/option-strict/Nothing.cs:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////////////
2 | // The MIT License (MIT)
3 | //
4 | // Copyright (c) 2014 Paul Louth
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in all
14 | // copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | // SOFTWARE.
23 | //
24 |
25 | using System;
26 |
27 | namespace Monad
28 | {
29 | ///
30 | /// Nothing case of the OptionStrict monad
31 | ///
32 | public class NothingStrict : OptionStrict
33 | {
34 | public override string ToString()
35 | {
36 | return "[Nothing]";
37 | }
38 |
39 | public override T Value
40 | {
41 | get
42 | {
43 | throw new InvalidOperationException("OptionStrict.Nothing has no value");
44 | }
45 | }
46 |
47 | public override bool HasValue
48 | {
49 | get
50 | {
51 | return false;
52 | }
53 | }
54 |
55 | public override R Match(Func Just, Func Nothing)
56 | {
57 | if (Just == null) throw new ArgumentNullException("Just");
58 | if (Nothing == null) throw new ArgumentNullException("Nothing");
59 | return Nothing();
60 | }
61 |
62 | public override R Match(Func Just, Func Nothing)
63 | {
64 | if (Just == null) throw new ArgumentNullException("Just");
65 | if (Nothing == null) throw new ArgumentNullException("Nothing");
66 | return Nothing();
67 | }
68 |
69 | public override R Match(Func Just, R Nothing)
70 | {
71 | if (Just == null) throw new ArgumentNullException("Just");
72 | return Nothing;
73 | }
74 |
75 | public override R Match(Func Just, R Nothing)
76 | {
77 | if (Just == null) throw new ArgumentNullException("Just");
78 | return Nothing;
79 | }
80 |
81 | ///
82 | /// Monadic append
83 | /// If the lhs or rhs are in a Nothing state then Nothing propagates
84 | ///
85 | public override OptionStrict Mappend(OptionStrict rhs)
86 | {
87 | if (rhs == null) throw new ArgumentNullException("rhs");
88 | return this;
89 | }
90 | }
91 | }
--------------------------------------------------------------------------------
/CSharpMonad/src/ext/TupleExt.cs:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////////////
2 | // The MIT License (MIT)
3 | //
4 | // Copyright (c) 2014 Paul Louth
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in all
14 | // copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | // SOFTWARE.
23 | //
24 |
25 | using System;
26 |
27 | namespace Monad
28 | {
29 | public static class TupleExtensions
30 | {
31 | public static R Apply(this Tuple self, Func func)
32 | {
33 | if (func == null) throw new ArgumentNullException("func");
34 | return func(self.Item1, self.Item2);
35 | }
36 |
37 | public static R Apply(this Tuple self, Func func)
38 | {
39 | if (func == null) throw new ArgumentNullException("func");
40 | return func(self.Item1, self.Item2, self.Item3);
41 | }
42 |
43 | public static R Apply(this Tuple self, Func func)
44 | {
45 | if (func == null) throw new ArgumentNullException("func");
46 | return func(self.Item1, self.Item2, self.Item3, self.Item4);
47 | }
48 |
49 | public static R Apply(this Tuple self, Func func)
50 | {
51 | if (func == null) throw new ArgumentNullException("func");
52 | return func(self.Item1, self.Item2, self.Item3, self.Item4, self.Item5);
53 | }
54 |
55 | public static void Apply(this Tuple self, Action func)
56 | {
57 | if (func == null) throw new ArgumentNullException("func");
58 | func(self.Item1, self.Item2);
59 | }
60 |
61 | public static void Apply(this Tuple self, Action func)
62 | {
63 | if (func == null) throw new ArgumentNullException("func");
64 | func(self.Item1, self.Item2, self.Item3);
65 | }
66 |
67 | public static void Apply(this Tuple self, Action func)
68 | {
69 | if (func == null) throw new ArgumentNullException("func");
70 | func(self.Item1, self.Item2, self.Item3, self.Item4);
71 | }
72 |
73 | public static void Apply(this Tuple self, Action func)
74 | {
75 | if (func == null) throw new ArgumentNullException("func");
76 | func(self.Item1, self.Item2, self.Item3, self.Item4, self.Item5);
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/CSharpMonad/src/parsec/ParserResult.cs:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////////////
2 | // The MIT License (MIT)
3 | //
4 | // Copyright (c) 2014 Paul Louth
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in all
14 | // copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | // SOFTWARE.
23 | //
24 |
25 | using System;
26 | using System.Collections.Generic;
27 | using Monad.Utility;
28 |
29 | namespace Monad.Parsec
30 | {
31 | public class ParserResult
32 | {
33 | public readonly ImmutableList>> Value;
34 | public readonly ImmutableList Errors;
35 |
36 | public ParserResult(ImmutableList>> value)
37 | {
38 | Value = value;
39 | }
40 |
41 | public ParserResult(Tuple>[] value)
42 | {
43 | Value = new ImmutableList>>(value);
44 | }
45 |
46 | public ParserResult(ImmutableList errors)
47 | {
48 | Value = new ImmutableList>>(new Tuple>[0]);
49 | Errors = errors;
50 | }
51 |
52 | public bool IsFaulted
53 | {
54 | get
55 | {
56 | return Errors != null;
57 | }
58 | }
59 | }
60 |
61 | public static class ParserResult
62 | {
63 | public static ParserResult Fail(ImmutableList errors)
64 | {
65 | return new ParserResult(errors);
66 | }
67 |
68 | public static ParserResult Fail(ParserError[] errors)
69 | {
70 | return new ParserResult(new ImmutableList(errors));
71 | }
72 |
73 | public static ParserResult Fail(ParserError error)
74 | {
75 | return new ParserResult(error.Cons());
76 | }
77 |
78 | public static ParserResult Fail(string expected, ImmutableList input, string message = "")
79 | {
80 | return new ParserResult(new ParserError(expected,input,message).Cons());
81 | }
82 |
83 | public static ParserResult Success(this ImmutableList>> self)
84 | {
85 | return new ParserResult(self);
86 | }
87 |
88 | public static ParserResult Success(this IEnumerable>> self)
89 | {
90 | return new ParserResult(new ImmutableList>>(self));
91 | }
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/CSharpMonad/src/ext/EnumerableExt.cs:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////////////
2 | // The MIT License (MIT)
3 | //
4 | // Copyright (c) 2014 Paul Louth
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in all
14 | // copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | // SOFTWARE.
23 | //
24 |
25 | using Monad.Parsec;
26 | using Monad.Utility;
27 | using System;
28 | using System.Collections.Generic;
29 | using System.Linq;
30 |
31 | namespace Monad
32 | {
33 | public static class EnumerableExt
34 | {
35 | public static T Head(this IEnumerable self)
36 | {
37 | return self.First();
38 | }
39 | public static IEnumerable Tail(this IEnumerable self)
40 | {
41 | return self.Skip(1);
42 | }
43 | public static T Second(this IEnumerable self)
44 | {
45 | return self.Tail().Head();
46 | }
47 |
48 | public static ImmutableList ToParserChar(this IEnumerable input)
49 | {
50 | int line = 1;
51 | int col = 1;
52 |
53 | var list = new List();
54 |
55 | foreach (var c in input)
56 | {
57 | if (c == '\r')
58 | {
59 | continue;
60 | }
61 |
62 | list.Add(new ParserChar(c, SrcLoc.Return(line, col)));
63 |
64 | if (c == '\n')
65 | {
66 | line++;
67 | col = 1;
68 | }
69 | col++;
70 | }
71 |
72 | return new ImmutableList(list);
73 | }
74 |
75 | ///
76 | /// Foldr
77 | ///
78 | public static U Foldr(this IEnumerable self, Func func, U state)
79 | {
80 | foreach (var item in self)
81 | {
82 | state = func(item, state);
83 | }
84 | return state;
85 | }
86 |
87 | ///
88 | /// Foldr
89 | ///
90 | public static U Foldr(this IEnumerable self, Func func, U state)
91 | {
92 | foreach (var item in self)
93 | {
94 | state = func(state);
95 | }
96 | return state;
97 | }
98 |
99 | ///
100 | /// Foldl
101 | ///
102 | public static U Foldl(this IEnumerable self, Func func, U state)
103 | {
104 | return self.Reverse().Foldr(func, state);
105 | }
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/CSharpMonad/src/parsec/token/ops/Ops.cs:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////////////
2 | // The MIT License (MIT)
3 | //
4 | // Copyright (c) 2014 Paul Louth
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in all
14 | // copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | // SOFTWARE.
23 | //
24 |
25 | using System.Linq;
26 | using Monad.Utility;
27 |
28 | namespace Monad.Parsec.Token.Ops
29 | {
30 | internal static class OpsHelper
31 | {
32 | ///
33 | /// TODO: Make this pay attention to the case-sensitivity settings
34 | ///
35 | internal static bool IsReservedOp(ImmutableList name, GeneralLanguageDef languageDef)
36 | {
37 | return languageDef.ReservedOpNames.Contains(name.AsString());
38 | }
39 | }
40 |
41 | public class ReservedOp : Parser
42 | {
43 | public ReservedOp(string name, GeneralLanguageDef languageDef)
44 | :
45 | base(
46 | inp => Tok.Lexeme(
47 | from op in Prim.String(name)
48 | from nf in Prim.NotFollowedBy( languageDef.OpLetter )
49 | .Fail("end of " + op.AsString())
50 | select new ReservedOpToken(op, inp.First().Location)
51 | )
52 | .Parse(inp)
53 | )
54 | { }
55 | }
56 |
57 | public class Operator : Parser
58 | {
59 | public Operator(GeneralLanguageDef languageDef)
60 | :
61 | base(
62 | inp =>
63 | {
64 | var res = Tok.Lexeme(
65 | from name in new Oper(languageDef)
66 | where !OpsHelper.IsReservedOp(name, languageDef)
67 | select new OperatorToken(name, inp.First().Location))
68 | .Parse(inp);
69 |
70 | if (res.IsFaulted)
71 | return res;
72 |
73 | if (res.Value.IsEmpty)
74 | return ParserResult.Fail("unexpected: reserved operator", inp);
75 |
76 | return res;
77 | }
78 | )
79 | { }
80 | }
81 |
82 | public class Oper : Parser>
83 | {
84 | public Oper(GeneralLanguageDef languageDef)
85 | :
86 | base(
87 | inp => (from c in languageDef.OpStart
88 | from cs in Prim.Many(languageDef.OpLetter)
89 | select c.Cons(cs))
90 | .Fail("operator")
91 | .Parse(inp)
92 | )
93 | {}
94 | }
95 |
96 | }
97 |
--------------------------------------------------------------------------------
/CSharpMonad.UnitTests/src/IOTests.cs:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////////////
2 | // The MIT License (MIT)
3 | //
4 | // Copyright (c) 2014 Paul Louth
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in all
14 | // copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | // SOFTWARE.
23 | //
24 |
25 | using System;
26 | using System.Collections.Generic;
27 | using System.Linq;
28 | using System.Text;
29 | using System.Threading.Tasks;
30 | using Monad;
31 | using Xunit;
32 | using System.Reflection;
33 | using System.IO;
34 | using Monad.Utility;
35 |
36 | namespace Monad.UnitTests
37 | {
38 | public class IOTests
39 | {
40 | [Fact]
41 | public void TestIOMonadLazyLoading()
42 | {
43 | var m = I.O(() =>
44 | System.IO.File.ReadAllBytes(Assembly.GetCallingAssembly().Location)
45 | );
46 |
47 | m ();
48 | }
49 |
50 | [Fact]
51 | public void TestIOMonadBinding()
52 | {
53 | string data = "Testing 123";
54 |
55 | var result = from tmpFileName in GetTempFileName()
56 | from _ in WriteFile(tmpFileName, data)
57 | from dataFromFile in ReadFile(tmpFileName)
58 | from __ in DeleteFile(tmpFileName)
59 | select dataFromFile;
60 |
61 | Assert.True(result.Invoke() == "Testing 123");
62 | }
63 |
64 | [Fact]
65 | public void TestIOMonadBindingFluent()
66 | {
67 | string data = "Testing 123";
68 |
69 | var result = GetTempFileName()
70 | .Then( tmpFileName => { WriteFile(tmpFileName, data)(); return tmpFileName; } )
71 | .Then( tmpFileName => { return new { tmpFileName, data = ReadFile(tmpFileName)() }; })
72 | .Then( context => { DeleteFile(context.tmpFileName)(); return context.data; } );
73 |
74 | Assert.True(result.Invoke() == "Testing 123");
75 | }
76 |
77 | private static IO DeleteFile(string tmpFileName)
78 | {
79 | return () =>
80 | Unit.Return(
81 | () => File.Delete(tmpFileName)
82 | );
83 | }
84 |
85 | private static IO ReadFile(string tmpFileName)
86 | {
87 | return () => File.ReadAllText(tmpFileName);
88 | }
89 |
90 | private static IO WriteFile(string tmpFileName, string data)
91 | {
92 | return () =>
93 | Unit.Return(
94 | () => File.WriteAllText(tmpFileName, data)
95 | );
96 | }
97 |
98 | private static IO GetTempFileName()
99 | {
100 | return () => Path.GetTempFileName();
101 | }
102 | }
103 | }
--------------------------------------------------------------------------------
/CSharpMonad/src/parsec/token/strings/Strings.cs:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////////////
2 | // The MIT License (MIT)
3 | //
4 | // Copyright (c) 2014 Paul Louth
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in all
14 | // copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | // SOFTWARE.
23 | //
24 |
25 | namespace Monad.Parsec.Token.Strings
26 | {
27 | public class StringLiteral : Parser
28 | {
29 | public StringLiteral()
30 | :
31 | base(
32 | inp => (from l in Tok.Lexeme(
33 | from str in Prim.Between(
34 | Prim.Character('"'),
35 | Prim.Character('"').Fail("end of string"),
36 | Prim.Many( new StringChar() )
37 | )
38 | select str
39 | )
40 | select new StringLiteralToken(l,inp.Head().Location)
41 | )
42 | .Fail("literal string")
43 | .Parse(inp)
44 | )
45 | { }
46 | }
47 |
48 | public class StringChar : Parser
49 | {
50 | public StringChar()
51 | :
52 | base(
53 | inp => (from c in new StringLetter()
54 | select c)
55 | .Or( new StringEscape() )
56 | .Fail("string character")
57 | .Parse(inp)
58 | )
59 | { }
60 | }
61 |
62 | public class StringLetter : Satisfy
63 | {
64 | public StringLetter()
65 | :
66 | base( c => (c != '"') && (c != '\\') && (c > 26), "string character" )
67 | { }
68 | }
69 |
70 | public class StringEscape : Parser
71 | {
72 | public StringEscape()
73 | :
74 | base(
75 | inp =>
76 | Prim.Character('\\')
77 | .And(
78 | new EscapeGap().And(Prim.Failure(ParserError.Create("", inp)))
79 | .Or(new EscapeEmpty().And(Prim.Failure(ParserError.Create("", inp))))
80 | .Or(Tok.Chars.EscapeCode())
81 | )
82 | .Parse(inp)
83 | )
84 | { }
85 | }
86 |
87 | public class EscapeGap : Parser
88 | {
89 | public EscapeGap()
90 | :
91 | base(
92 | inp => (from sp in Prim.Many1(Prim.Character(' '))
93 | from ch in Prim.Character('\\')
94 | select ch)
95 | .Fail("end of string gap")
96 | .Parse(inp)
97 | )
98 | {}
99 | }
100 |
101 | public class EscapeEmpty : Character
102 | {
103 | public EscapeEmpty()
104 | :
105 | base('&')
106 | { }
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/CSharpMonad/src/Reader.cs:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////////////
2 | // The MIT License (MIT)
3 | //
4 | // Copyright (c) 2014 Paul Louth
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in all
14 | // copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | // SOFTWARE.
23 | //
24 |
25 | using System;
26 |
27 | namespace Monad
28 | {
29 | ///
30 | /// The reader monad
31 | /// Allows for an 'environment' value to be carried through bind functions
32 | ///
33 | /// Environment
34 | /// The underlying monadic type
35 | public delegate A Reader(E environment);
36 |
37 | ///
38 | /// Reader.
39 | ///
40 | public static class Reader
41 | {
42 | public static Reader Return(A value = default(A))
43 | {
44 | return (E env) => value;
45 | }
46 |
47 | public static Reader Ask(Func f)
48 | {
49 | if (f == null) throw new ArgumentNullException("f");
50 | return (E env) => f(env);
51 | }
52 |
53 | public static Reader Ask()
54 | {
55 | return (E env) => env;
56 | }
57 | }
58 |
59 | ///
60 | /// Reader monad extensions
61 | ///
62 | public static class ReaderExt
63 | {
64 | public static Reader Ask(this Reader self, Func f)
65 | {
66 | if (f == null) throw new ArgumentNullException("f");
67 | return (E env) => f(env);
68 | }
69 |
70 | public static Reader Ask(this Reader self)
71 | {
72 | return (E env) => env;
73 | }
74 |
75 | ///
76 | /// Select
77 | ///
78 | public static Reader Select(this Reader self, Func select)
79 | {
80 | if (select == null) throw new ArgumentNullException("select");
81 | return (E env) => select(self(env));
82 | }
83 |
84 | ///
85 | /// Select Many
86 | ///
87 | public static Reader SelectMany(
88 | this Reader self,
89 | Func> bind,
90 | Func project
91 | )
92 | {
93 | if (bind == null) throw new ArgumentNullException("bind");
94 | if (project == null) throw new ArgumentNullException("project");
95 | return (E env) =>
96 | {
97 | var resT = self(env);
98 | var resU = bind(resT);
99 | var resV = project(resT, resU(env));
100 | return resV;
101 | };
102 | }
103 |
104 | ///
105 | /// Memoize the result
106 | ///
107 | public static Func Memo(this Reader self, E environment)
108 | {
109 | var res = self(environment);
110 | return () => res;
111 | }
112 |
113 | }
114 | }
--------------------------------------------------------------------------------
/CSharpMonad/src/parsec/token/idents/Idents.cs:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////////////////////
2 | // The MIT License (MIT)
3 | //
4 | // Copyright (c) 2014 Paul Louth
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in all
14 | // copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | // SOFTWARE.
23 | //
24 |
25 | using System.Linq;
26 | using Monad.Utility;
27 |
28 | namespace Monad.Parsec.Token.Idents
29 | {
30 | internal static class IdentHelper
31 | {
32 |
33 | ///
34 | /// TODO: Make this pay attention to the case-sensitivity settings
35 | ///
36 | internal static Parser> CaseString(string str, GeneralLanguageDef languageDef)
37 | {
38 | return Prim.String(str);
39 | }
40 |
41 | ///
42 | /// TODO: Make this pay attention to the case-sensitivity settings
43 | ///
44 | internal static bool IsReservedName(ImmutableList name, GeneralLanguageDef languageDef)
45 | {
46 | return languageDef.ReservedNames.Contains(name.AsString());
47 | }
48 | }
49 |
50 | public class Reserved : Parser
51 | {
52 | public Reserved(string name, GeneralLanguageDef languageDef)
53 | :
54 | base(
55 | inp => Tok.Lexeme(
56 | from cs in IdentHelper.CaseString(name, languageDef)
57 | from nf in Prim.NotFollowedBy( languageDef.IdentLetter )
58 | .Fail("end of " + cs.AsString())
59 | select new ReservedToken(cs,inp.Head().Location)
60 | )
61 | .Parse(inp)
62 | )
63 | { }
64 | }
65 |
66 | public class Identifier : Parser
67 | {
68 | public Identifier(GeneralLanguageDef languageDef)
69 | :
70 | base(
71 | inp =>
72 | {
73 | var res = Tok.Lexeme(
74 | from name in new Ident(languageDef)
75 | where !IdentHelper.IsReservedName(name, languageDef)
76 | select new IdentifierToken(name, inp.First().Location)
77 | )
78 | .Parse(inp);
79 |
80 | if (res.IsFaulted)
81 | return res;
82 |
83 | if (res.Value.IsEmpty)
84 | return ParserResult.Fail("unexpected: reserved word",inp);
85 |
86 | return res;
87 | }
88 | )
89 | { }
90 | }
91 |
92 | public class Ident : Parser>
93 | {
94 | public Ident(GeneralLanguageDef languageDef)
95 | :
96 | base(
97 | inp =>(from c in languageDef.IdentStart
98 | from cs in Prim.Many(languageDef.IdentLetter)
99 | select c.Cons(cs))
100 | .Fail("identifier")
101 | .Parse(inp)
102 | )
103 | {}
104 | }
105 |
106 | }
107 |
--------------------------------------------------------------------------------
/CSharpMonad/src/utility/Memoize.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace Monad.Utility
5 | {
6 | ///
7 | /// Create a memoized value
8 | ///
9 | public static class Memo
10 | {
11 | ///
12 | /// Create a memoized (cached) value, doesn't calculate the provided expression until the
13 | /// value is required, and once it has been calculated it will cache the value for future
14 | /// access.
15 | ///
16 | public static Memo ize(Func func)
17 | {
18 | if (func == null) throw new ArgumentNullException("func");
19 | return new Memo(func);
20 | }
21 | }
22 |
23 | ///
24 | /// Create a memoized (cached) value, doesn't calculate the provided expression until the
25 | /// value is required, and once it has been calculated it will cache the value for future
26 | /// access.
27 | ///
28 | ///
29 | public class Memo
30 | {
31 | readonly Func func;
32 | WeakReference reference;
33 |
34 | ///
35 | /// Ctor
36 | ///
37 | /// Function to invoke to get the value when needed
38 | public Memo(Func func)
39 | {
40 | if (func == null) throw new ArgumentNullException("func");
41 | this.func = func;
42 | }
43 |
44 | ///
45 | /// Access the value (this will cause the calculation if the value hasn't yet
46 | /// been memoized).
47 | ///
48 | public T Value
49 | {
50 | get
51 | {
52 | if (reference == null)
53 | {
54 | reference = new WeakReference(func());
55 | }
56 | else if (!reference.IsAlive)
57 | {
58 | reference.Target = func();
59 | }
60 | return (T)reference.Target;
61 | }
62 | }
63 |
64 | public bool HasValue
65 | {
66 | get
67 | {
68 | return reference != null && reference.IsAlive;
69 | }
70 | }
71 |
72 | ///
73 | /// Forget the memoized value
74 | ///
75 | public void Forget()
76 | {
77 | reference = null;
78 | }
79 |
80 | ///
81 | /// Allows implicit conversion from the Memo to T.
82 | ///
83 | public static implicit operator T(Memo memo)
84 | {
85 | return memo.Value;
86 | }
87 | }
88 |
89 | ///
90 | /// Extension method for Func
91 | ///
92 | public static class MemoExt
93 | {
94 | ///
95 | /// Memoize the function
96 | ///
97 | public static Func Memo(this Func