From 1b664d5bd7a9810cfd9786531d255814dc0edc2b Mon Sep 17 00:00:00 2001 From: Ondra Pelech Date: Sat, 15 Oct 2016 23:20:08 +0200 Subject: [PATCH] ProjectScaffold-ize this adds support for cool stuff, like packaging, tests, etc --- .gitattributes | 83 ++--- .github/ISSUE_TEMPLATE.md | 30 ++ .gitignore | 53 ++- .paket/paket.bootstrapper.exe | Bin 0 -> 39936 bytes .paket/paket.targets | 36 ++ .travis.yml | 9 + Higher.sln | 59 ++- LICENSE.md => LICENSE.txt | 0 README.md | 17 +- RELEASE_NOTES.md | 2 + appveyor.yml | 9 + build.cmd | 18 + build.fsx | 404 +++++++++++++++++++++ build.sh | 77 ++++ docs/content/index.fsx | 67 ++++ docs/content/tutorial.fsx | 19 + docs/files/img/logo-template.pdn | Bin 0 -> 15052 bytes docs/files/img/logo.png | Bin 0 -> 1581 bytes docs/tools/generate.fsx | 145 ++++++++ docs/tools/templates/template.cshtml | 58 +++ lib/README.md | 11 + paket.dependencies | 18 + paket.lock | 32 ++ src/Higher.Core/Algebra.fs | 5 - src/Higher.Core/Higher.Core.fsproj | 116 ------ src/{Higher.Core => Higher}/Adjunction.fs | 24 +- src/Higher/Algebra.fs | 5 + src/Higher/App.config | 10 + src/{Higher.Core => Higher}/Applicative.fs | 12 +- src/{Higher.Core => Higher}/Arrow.fs | 4 +- src/{Higher.Core => Higher}/Category.fs | 8 +- src/{Higher.Core => Higher}/Choice.fs | 14 +- src/{Higher.Core => Higher}/CoYoneda.fs | 34 +- src/{Higher.Core => Higher}/Codensity.fs | 24 +- src/{Higher.Core => Higher}/Cofree.fs | 20 +- src/{Higher.Core => Higher}/Comonad.fs | 16 +- src/{Higher.Core => Higher}/Compose.fs | 21 +- src/{Higher.Core => Higher}/Const.fs | 11 +- src/{Higher.Core => Higher}/Cont.fs | 20 +- src/{Higher.Core => Higher}/ContT.fs | 32 +- src/{Higher.Core => Higher}/Coproduct.fs | 91 ++--- src/{Higher.Core => Higher}/CoreTypes.fs | 30 +- src/{Higher.Core => Higher}/FFree.fs | 28 +- src/{Higher.Core => Higher}/FTLens.fs | 25 +- src/{Higher.Core => Higher}/Fix.fs | 15 +- src/{Higher.Core => Higher}/Flip.fs | 9 +- src/{Higher.Core => Higher}/Free.fs | 19 +- src/{Higher.Core => Higher}/Fun.fs | 20 +- src/{Higher.Core => Higher}/Functor.fs | 28 +- src/Higher/Higher.fsproj | 185 ++++++++++ src/{Higher.Core => Higher}/Identity.fs | 8 +- src/{Higher.Core => Higher}/Index.fs | 25 +- src/{Higher.Core => Higher}/Kleisli.fs | 22 +- src/{Higher.Core => Higher}/LeftKan.fs | 35 +- src/{Higher.Core => Higher}/Leibniz.fs | 19 +- src/{Higher.Core => Higher}/List.fs | 34 +- src/{Higher.Core => Higher}/ListT.fs | 38 +- src/{Higher.Core => Higher}/Monad.fs | 33 +- src/{Higher.Core => Higher}/MonadTrans.fs | 6 +- src/{Higher.Core => Higher}/Monoid.fs | 28 +- src/{Higher.Core => Higher}/Option.fs | 15 +- src/{Higher.Core => Higher}/OptionT.fs | 34 +- src/{Higher.Core => Higher}/PerfectTree.fs | 10 +- src/{Higher.Core => Higher}/Reader.fs | 20 +- src/{Higher.Core => Higher}/ReaderT.fs | 31 +- src/{Higher.Core => Higher}/RightKan.fs | 27 +- src/{Higher.Core => Higher}/Script.fsx | 31 +- src/{Higher.Core => Higher}/Seq.fs | 22 +- src/{Higher.Core => Higher}/State.fs | 26 +- src/{Higher.Core => Higher}/StateT.fs | 34 +- src/{Higher.Core => Higher}/Traversable.fs | 12 +- src/{Higher.Core => Higher}/Tuple.fs | 12 +- src/{Higher.Core => Higher}/Writer.fs | 18 +- src/{Higher.Core => Higher}/WriterT.fs | 27 +- src/{Higher.Core => Higher}/Yoneda.fs | 20 +- src/Higher/paket.references | 1 + src/Higher/paket.template | 25 ++ tests/Higher.Tests/App.config | 10 + tests/Higher.Tests/Higher.Tests.fsproj | 131 +++++-- tests/Higher.Tests/ListF.fsx | 38 +- tests/Higher.Tests/Tests.fs | 18 + tests/Higher.Tests/paket.references | 4 + 82 files changed, 1962 insertions(+), 825 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE.md create mode 100755 .paket/paket.bootstrapper.exe create mode 100644 .paket/paket.targets create mode 100644 .travis.yml rename LICENSE.md => LICENSE.txt (100%) create mode 100644 RELEASE_NOTES.md create mode 100644 appveyor.yml create mode 100644 build.cmd create mode 100644 build.fsx create mode 100755 build.sh create mode 100644 docs/content/index.fsx create mode 100644 docs/content/tutorial.fsx create mode 100644 docs/files/img/logo-template.pdn create mode 100644 docs/files/img/logo.png create mode 100644 docs/tools/generate.fsx create mode 100644 docs/tools/templates/template.cshtml create mode 100644 lib/README.md create mode 100644 paket.dependencies create mode 100644 paket.lock delete mode 100644 src/Higher.Core/Algebra.fs delete mode 100644 src/Higher.Core/Higher.Core.fsproj rename src/{Higher.Core => Higher}/Adjunction.fs (68%) create mode 100644 src/Higher/Algebra.fs create mode 100644 src/Higher/App.config rename src/{Higher.Core => Higher}/Applicative.fs (54%) rename src/{Higher.Core => Higher}/Arrow.fs (91%) rename src/{Higher.Core => Higher}/Category.fs (58%) rename src/{Higher.Core => Higher}/Choice.fs (81%) rename src/{Higher.Core => Higher}/CoYoneda.fs (71%) rename src/{Higher.Core => Higher}/Codensity.fs (76%) rename src/{Higher.Core => Higher}/Cofree.fs (88%) rename src/{Higher.Core => Higher}/Comonad.fs (92%) rename src/{Higher.Core => Higher}/Compose.fs (82%) rename src/{Higher.Core => Higher}/Const.fs (73%) rename src/{Higher.Core => Higher}/Cont.fs (75%) rename src/{Higher.Core => Higher}/ContT.fs (69%) rename src/{Higher.Core => Higher}/Coproduct.fs (59%) rename src/{Higher.Core => Higher}/CoreTypes.fs (71%) rename src/{Higher.Core => Higher}/FFree.fs (76%) rename src/{Higher.Core => Higher}/FTLens.fs (72%) rename src/{Higher.Core => Higher}/Fix.fs (77%) rename src/{Higher.Core => Higher}/Flip.fs (91%) rename src/{Higher.Core => Higher}/Free.fs (73%) rename src/{Higher.Core => Higher}/Fun.fs (62%) rename src/{Higher.Core => Higher}/Functor.fs (83%) create mode 100644 src/Higher/Higher.fsproj rename src/{Higher.Core => Higher}/Identity.fs (94%) rename src/{Higher.Core => Higher}/Index.fs (63%) rename src/{Higher.Core => Higher}/Kleisli.fs (81%) rename src/{Higher.Core => Higher}/LeftKan.fs (74%) rename src/{Higher.Core => Higher}/Leibniz.fs (80%) rename src/{Higher.Core => Higher}/List.fs (58%) rename src/{Higher.Core => Higher}/ListT.fs (52%) rename src/{Higher.Core => Higher}/Monad.fs (78%) rename src/{Higher.Core => Higher}/MonadTrans.fs (68%) rename src/{Higher.Core => Higher}/Monoid.fs (75%) rename src/{Higher.Core => Higher}/Option.fs (54%) rename src/{Higher.Core => Higher}/OptionT.fs (63%) rename src/{Higher.Core => Higher}/PerfectTree.fs (74%) rename src/{Higher.Core => Higher}/Reader.fs (69%) rename src/{Higher.Core => Higher}/ReaderT.fs (69%) rename src/{Higher.Core => Higher}/RightKan.fs (81%) rename src/{Higher.Core => Higher}/Script.fsx (82%) rename src/{Higher.Core => Higher}/Seq.fs (55%) rename src/{Higher.Core => Higher}/State.fs (66%) rename src/{Higher.Core => Higher}/StateT.fs (72%) rename src/{Higher.Core => Higher}/Traversable.fs (68%) rename src/{Higher.Core => Higher}/Tuple.fs (73%) rename src/{Higher.Core => Higher}/Writer.fs (76%) rename src/{Higher.Core => Higher}/WriterT.fs (75%) rename src/{Higher.Core => Higher}/Yoneda.fs (78%) create mode 100644 src/Higher/paket.references create mode 100644 src/Higher/paket.template create mode 100644 tests/Higher.Tests/App.config create mode 100644 tests/Higher.Tests/Tests.fs create mode 100644 tests/Higher.Tests/paket.references diff --git a/.gitattributes b/.gitattributes index 1ff0c42..7ff73f4 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,63 +1,26 @@ -############################################################################### -# Set default behavior to automatically normalize line endings. -############################################################################### +# Auto detect text files * text=auto -############################################################################### -# Set default behavior for command prompt diff. -# -# This is need for earlier builds of msysgit that does not have it on by -# default for csharp files. -# Note: This is only used by command line -############################################################################### -#*.cs diff=csharp +# Custom for Visual Studio +*.cs diff=csharp text=auto eol=lf +*.vb diff=csharp text=auto eol=lf +*.fs diff=csharp text=auto eol=lf +*.fsi diff=csharp text=auto eol=lf +*.fsx diff=csharp text=auto eol=lf +*.sln text eol=crlf merge=union +*.csproj merge=union +*.vbproj merge=union +*.fsproj merge=union +*.dbproj merge=union -############################################################################### -# Set the merge driver for project and solution files -# -# Merging from the command prompt will add diff markers to the files if there -# are conflicts (Merging from VS is not affected by the settings below, in VS -# the diff markers are never inserted). Diff markers may cause the following -# file extensions to fail to load in VS. An alternative would be to treat -# these files as binary and thus will always conflict and require user -# intervention with every merge. To do so, just uncomment the entries below -############################################################################### -#*.sln merge=binary -#*.csproj merge=binary -#*.vbproj merge=binary -#*.vcxproj merge=binary -#*.vcproj merge=binary -#*.dbproj merge=binary -#*.fsproj merge=binary -#*.lsproj merge=binary -#*.wixproj merge=binary -#*.modelproj merge=binary -#*.sqlproj merge=binary -#*.wwaproj merge=binary - -############################################################################### -# behavior for image files -# -# image files are treated as binary by default. -############################################################################### -#*.jpg binary -#*.png binary -#*.gif binary - -############################################################################### -# diff behavior for common document formats -# -# Convert binary document formats to text before diffing them. This feature -# is only available from the command line. Turn it on by uncommenting the -# entries below. -############################################################################### -#*.doc diff=astextplain -#*.DOC diff=astextplain -#*.docx diff=astextplain -#*.DOCX diff=astextplain -#*.dot diff=astextplain -#*.DOT diff=astextplain -#*.pdf diff=astextplain -#*.PDF diff=astextplain -#*.rtf diff=astextplain -#*.RTF diff=astextplain +# Standard to msysgit +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..86eed43 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,30 @@ +### Description + +Please provide a succinct description of your issue. + +### Repro steps + +Please provide the steps required to reproduce the problem + +1. Step A + +2. Step B + +### Expected behavior + +Please provide a description of the behavior you expect. + +### Actual behavior + +Please provide a description of the actual behavior you observe. + +### Known workarounds + +Please provide a description of any known workarounds. + +### Related information + +* Operating system +* Branch +* .NET Runtime, CoreCLR or Mono Version +* Performance information, links to performance testing scripts diff --git a/.gitignore b/.gitignore index f2b1147..27bcb45 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,11 @@ *.user *.sln.docstates +# Xamarin Studio / monodevelop user-specific +*.userprefs +*.dll.mdb +*.exe.mdb + # Build results [Dd]ebug/ @@ -15,12 +20,6 @@ build/ [Bb]in/ [Oo]bj/ -# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets -!packages/*/build/ - -#NuGet -packages/ - # MSTest test Results [Tt]est[Rr]esult*/ [Bb]uild[Ll]og.* @@ -62,6 +61,9 @@ ipch/ *.vsp *.vspx +# Other Visual Studio data +.vs/ + # Guidance Automation Toolkit *.gpState @@ -98,9 +100,8 @@ publish/ # Publish Web Output *.Publish.xml -# NuGet Packages Directory -## TODO: If you have NuGet Package Restore enabled, uncomment the next line -#packages/ +# Enable nuget.exe in the .nuget folder (though normally executables are not tracked) +!.nuget/NuGet.exe # Windows Azure Build Output csx @@ -109,6 +110,9 @@ csx # Windows Store app package directory AppPackages/ +# VSCode +.vscode/ + # Others sql/ *.Cache @@ -157,3 +161,34 @@ $RECYCLE.BIN/ # Mac desktop service store files .DS_Store + +# =================================================== +# Exclude F# project specific directories and files +# =================================================== + +# NuGet Packages Directory +packages/ + +# Generated documentation folder +docs/output/ + +# Temp folder used for publishing docs +temp/ + +# Test results produced by build +TestResults.xml + +# Nuget outputs +nuget/*.nupkg +release.cmd +release.sh +localpackages/ +paket-files +*.orig +.paket/paket.exe +docs/content/license.md +docs/content/release-notes.md +.fake +docs/tools/FSharp.Formatting.svclog +AssemblyInfo.fs + diff --git a/.paket/paket.bootstrapper.exe b/.paket/paket.bootstrapper.exe new file mode 100755 index 0000000000000000000000000000000000000000..84cfeb9fef9252624993c907a3a0b8a52e5ef54b GIT binary patch literal 39936 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 qqd@mXGqOei!=f4P4B + + + + true + + true + $(MSBuildThisFileDirectory) + $(MSBuildThisFileDirectory)..\ + + + + $(PaketToolsPath)paket.exe + $(PaketToolsPath)paket.bootstrapper.exe + "$(PaketExePath)" + mono --runtime=v4.0.30319 "$(PaketExePath)" + "$(PaketBootStrapperExePath)" + mono --runtime=v4.0.30319 $(PaketBootStrapperExePath) + + $(PaketCommand) restore + $(PaketBootStrapperCommand) + + RestorePackages; $(BuildDependsOn); + + + + + + + + + + + + + diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..5152d90 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,9 @@ +language: csharp + +sudo: false # use the new container-based Travis infrastructure + +before_install: + - chmod +x build.sh + +script: + - ./build.sh All diff --git a/Higher.sln b/Higher.sln index ac59fec..7dc093f 100644 --- a/Higher.sln +++ b/Higher.sln @@ -1,13 +1,38 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.21005.1 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Higher.Core", "src\Higher.Core\Higher.Core.fsproj", "{C979A279-D345-469C-84B9-DACCFDE18FFD}" +# Visual Studio 2012 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".paket", ".paket", "{63297B98-5CED-492C-A5B7-A5B4F73CF142}" + ProjectSection(SolutionItems) = preProject + paket.dependencies = paket.dependencies + paket.lock = paket.lock + EndProjectSection EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Higher.Tests", "tests\Higher.Tests\Higher.Tests.fsproj", "{79CEA165-5660-4635-9854-FA3433E8CA86}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{A6A6AF7D-D6E3-442D-9B1E-58CC91879BE1}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{BF71DC5C-2815-4B55-A3F2-4636DD267EB0}" +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Higher", "src\Higher\Higher.fsproj", "{A76FEEB6-CF93-465D-8F57-D729C1FFFE76}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "project", "project", "{BF60BC93-E09B-4E5F-9D85-95A519479D54}" + ProjectSection(SolutionItems) = preProject + build.fsx = build.fsx + README.md = README.md + RELEASE_NOTES.md = RELEASE_NOTES.md + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{83F16175-43B1-4C90-A1EE-8E351C33435D}" + ProjectSection(SolutionItems) = preProject + docs\tools\generate.fsx = docs\tools\generate.fsx + docs\tools\templates\template.cshtml = docs\tools\templates\template.cshtml + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "content", "content", "{8E6D5255-776D-4B61-85F9-73C37AA1FB9A}" + ProjectSection(SolutionItems) = preProject + docs\content\index.fsx = docs\content\index.fsx + docs\content\tutorial.fsx = docs\content\tutorial.fsx + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{ED8079DD-2B06-4030-9F0F-DC548F98E1C4}" +EndProject +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Higher.Tests", "tests\Higher.Tests\Higher.Tests.fsproj", "{5BFF3686-D94A-438B-84EE-6390FA1E82EB}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -15,19 +40,21 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {C979A279-D345-469C-84B9-DACCFDE18FFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C979A279-D345-469C-84B9-DACCFDE18FFD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C979A279-D345-469C-84B9-DACCFDE18FFD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C979A279-D345-469C-84B9-DACCFDE18FFD}.Release|Any CPU.Build.0 = Release|Any CPU - {79CEA165-5660-4635-9854-FA3433E8CA86}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {79CEA165-5660-4635-9854-FA3433E8CA86}.Debug|Any CPU.Build.0 = Debug|Any CPU - {79CEA165-5660-4635-9854-FA3433E8CA86}.Release|Any CPU.ActiveCfg = Release|Any CPU - {79CEA165-5660-4635-9854-FA3433E8CA86}.Release|Any CPU.Build.0 = Release|Any CPU + {A76FEEB6-CF93-465D-8F57-D729C1FFFE76}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A76FEEB6-CF93-465D-8F57-D729C1FFFE76}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A76FEEB6-CF93-465D-8F57-D729C1FFFE76}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A76FEEB6-CF93-465D-8F57-D729C1FFFE76}.Release|Any CPU.Build.0 = Release|Any CPU + {5BFF3686-D94A-438B-84EE-6390FA1E82EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5BFF3686-D94A-438B-84EE-6390FA1E82EB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5BFF3686-D94A-438B-84EE-6390FA1E82EB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5BFF3686-D94A-438B-84EE-6390FA1E82EB}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {79CEA165-5660-4635-9854-FA3433E8CA86} = {BF71DC5C-2815-4B55-A3F2-4636DD267EB0} + {83F16175-43B1-4C90-A1EE-8E351C33435D} = {A6A6AF7D-D6E3-442D-9B1E-58CC91879BE1} + {8E6D5255-776D-4B61-85F9-73C37AA1FB9A} = {A6A6AF7D-D6E3-442D-9B1E-58CC91879BE1} + {5BFF3686-D94A-438B-84EE-6390FA1E82EB} = {ED8079DD-2B06-4030-9F0F-DC548F98E1C4} EndGlobalSection EndGlobal diff --git a/LICENSE.md b/LICENSE.txt similarity index 100% rename from LICENSE.md rename to LICENSE.txt diff --git a/README.md b/README.md index 6facfbf..8f1165e 100644 --- a/README.md +++ b/README.md @@ -3,10 +3,19 @@ Higher A lightweight library of abstractions for Higher-kinded programming in F#, based on -      [Lightweight Higher-Kinded Polymorphism][flops-2014-paper]
-      Jeremy Yallop and Leo White
-      Functional and Logic Programming 2014
-      [OCaml implementation][ocaml-implementation]
+> [Lightweight Higher-Kinded Polymorphism][flops-2014-paper] +> +> Jeremy Yallop and Leo White +> +> Functional and Logic Programming 2014 +> +> [OCaml implementation][ocaml-implementation] [flops-2014-paper]: https://ocamllabs.github.io/higher/lightweight-higher-kinded-polymorphism.pdf [ocaml-implementation]: https://github.com/ocamllabs/higher + +## Build Status + +Mono | .NET +---- | ---- +[![Mono CI Build Status](https://img.shields.io/travis/palladin/Higher/master.svg)](https://travis-ci.org/palladin/Higher) | [![.NET Build Status](https://img.shields.io/appveyor/ci/palladin/Higher/master.svg)](https://ci.appveyor.com/project/palladin/Higher) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md new file mode 100644 index 0000000..b23e80f --- /dev/null +++ b/RELEASE_NOTES.md @@ -0,0 +1,2 @@ +#### 1.0 - October 17 2016 +* Initial release diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..413e403 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,9 @@ +init: + - git config --global core.autocrlf input +build_script: + - cmd: build.cmd All +test: off +version: 0.0.1.{build} +artifacts: + - path: bin + name: bin diff --git a/build.cmd b/build.cmd new file mode 100644 index 0000000..09b44ff --- /dev/null +++ b/build.cmd @@ -0,0 +1,18 @@ +@echo off +cls + +.paket\paket.bootstrapper.exe +if errorlevel 1 ( + exit /b %errorlevel% +) + +.paket\paket.exe restore +if errorlevel 1 ( + exit /b %errorlevel% +) + +IF NOT EXIST build.fsx ( + .paket\paket.exe update + packages\build\FAKE\tools\FAKE.exe init.fsx +) +packages\build\FAKE\tools\FAKE.exe build.fsx %* diff --git a/build.fsx b/build.fsx new file mode 100644 index 0000000..beb7a63 --- /dev/null +++ b/build.fsx @@ -0,0 +1,404 @@ +// -------------------------------------------------------------------------------------- +// FAKE build script +// -------------------------------------------------------------------------------------- + +#r @"packages/build/FAKE/tools/FakeLib.dll" +open Fake +open Fake.Git +open Fake.AssemblyInfoFile +open Fake.ReleaseNotesHelper +open Fake.UserInputHelper +open System +open System.IO +#if MONO +#else +#load "packages/build/SourceLink.Fake/tools/Fake.fsx" +open SourceLink +#endif + +// -------------------------------------------------------------------------------------- +// START TODO: Provide project-specific details below +// -------------------------------------------------------------------------------------- + +// Information about the project are used +// - for version and project name in generated AssemblyInfo file +// - by the generated NuGet package +// - to run tests and to publish documentation on GitHub gh-pages +// - for documentation, you also need to edit info in "docs/tools/generate.fsx" + +// The name of the project +// (used by attributes in AssemblyInfo, name of a NuGet package and directory in 'src') +let project = "Higher" + +// Short summary of the project +// (used as description in AssemblyInfo and as a short summary for NuGet package) +let summary = "Lightweight Higher-Kinded Polymorphism" + +// Longer description of the project +// (used as a description for NuGet package; line breaks are automatically cleaned up) +let description = "A lightweight library of abstractions for Higher-kinded programming in F#, based on Lightweight Higher-Kinded Polymorphism" + +// List of author names (for NuGet package) +let authors = [ "palladin" ] + +// Tags for your project (for NuGet package) +let tags = "kind kinds Higher-kinded functor applicative monad algebra" + +// File system information +let solutionFile = "Higher.sln" + +// Pattern specifying assemblies to be tested using NUnit +let testAssemblies = "tests/**/bin/Release/*Tests*.dll" + +// Git configuration (used for publishing documentation in gh-pages branch) +// The profile where the project is posted +let gitOwner = "palladin" +let gitHome = sprintf "%s/%s" "https://github.com" gitOwner + +// The name of the project on GitHub +let gitName = "Higher" + +// The url for the raw files hosted +let gitRaw = environVarOrDefault "gitRaw" "https://raw.githubusercontent.com/palladin" + +// -------------------------------------------------------------------------------------- +// END TODO: The rest of the file includes standard build steps +// -------------------------------------------------------------------------------------- + +// Read additional information from the release notes document +let release = LoadReleaseNotes "RELEASE_NOTES.md" + +// Helper active pattern for project types +let (|Fsproj|Csproj|Vbproj|Shproj|) (projFileName:string) = + match projFileName with + | f when f.EndsWith("fsproj") -> Fsproj + | f when f.EndsWith("csproj") -> Csproj + | f when f.EndsWith("vbproj") -> Vbproj + | f when f.EndsWith("shproj") -> Shproj + | _ -> failwith (sprintf "Project file %s not supported. Unknown project type." projFileName) + +// Generate assembly info files with the right version & up-to-date information +Target "AssemblyInfo" (fun _ -> + let getAssemblyInfoAttributes projectName = + [ Attribute.Title (projectName) + Attribute.Product project + Attribute.Description summary + Attribute.Version release.AssemblyVersion + Attribute.FileVersion release.AssemblyVersion ] + + let getProjectDetails projectPath = + let projectName = System.IO.Path.GetFileNameWithoutExtension(projectPath) + ( projectPath, + projectName, + System.IO.Path.GetDirectoryName(projectPath), + (getAssemblyInfoAttributes projectName) + ) + + !! "src/**/*.??proj" + |> Seq.map getProjectDetails + |> Seq.iter (fun (projFileName, projectName, folderName, attributes) -> + match projFileName with + | Fsproj -> CreateFSharpAssemblyInfo (folderName "AssemblyInfo.fs") attributes + | Csproj -> CreateCSharpAssemblyInfo ((folderName "Properties") "AssemblyInfo.cs") attributes + | Vbproj -> CreateVisualBasicAssemblyInfo ((folderName "My Project") "AssemblyInfo.vb") attributes + | Shproj -> () + ) +) + +// Copies binaries from default VS location to expected bin folder +// But keeps a subdirectory structure for each project in the +// src folder to support multiple project outputs +Target "CopyBinaries" (fun _ -> + !! "src/**/*.??proj" + -- "src/**/*.shproj" + |> Seq.map (fun f -> ((System.IO.Path.GetDirectoryName f) "bin/Release", "bin" (System.IO.Path.GetFileNameWithoutExtension f))) + |> Seq.iter (fun (fromDir, toDir) -> CopyDir toDir fromDir (fun _ -> true)) +) + +// -------------------------------------------------------------------------------------- +// Clean build results + +Target "Clean" (fun _ -> + !! solutionFile |> MSBuildRelease "" "Clean" |> ignore + CleanDirs ["bin"; "temp"; "docs/output"] +) + +// -------------------------------------------------------------------------------------- +// Build library & test project + +Target "Build" (fun _ -> + !! solutionFile +#if MONO + |> MSBuildReleaseExt "" [ ("DefineConstants","MONO") ] "Build" +#else + |> MSBuildRelease "" "Build" +#endif + |> ignore +) + +// -------------------------------------------------------------------------------------- +// Run the unit tests using test runner + +Target "RunTests" (fun _ -> + !! testAssemblies + |> NUnit (fun p -> + { p with + DisableShadowCopy = true + TimeOut = TimeSpan.FromMinutes 20. + OutputFile = "TestResults.xml" }) +) + +#if MONO +#else +// -------------------------------------------------------------------------------------- +// SourceLink allows Source Indexing on the PDB generated by the compiler, this allows +// the ability to step through the source code of external libraries http://ctaggart.github.io/SourceLink/ + +Target "SourceLink" (fun _ -> + let baseUrl = sprintf "%s/%s/{0}/%%var2%%" gitRaw project + !! "src/**/*.??proj" + -- "src/**/*.shproj" + |> Seq.iter (fun projFile -> + let proj = VsProj.LoadRelease projFile + SourceLink.Index proj.CompilesNotLinked proj.OutputFilePdb __SOURCE_DIRECTORY__ baseUrl + ) +) + +#endif + +// -------------------------------------------------------------------------------------- +// Build a NuGet package + +Target "NuGet" (fun _ -> + Paket.Pack(fun p -> + { p with + OutputPath = "bin" + Version = release.NugetVersion + ReleaseNotes = toLines release.Notes}) +) + +Target "PublishNuget" (fun _ -> + Paket.Push(fun p -> + { p with + WorkingDir = "bin" }) +) + + +// -------------------------------------------------------------------------------------- +// Generate the documentation + + +let fakePath = "packages" "build" "FAKE" "tools" "FAKE.exe" +let fakeStartInfo script workingDirectory args fsiargs environmentVars = + (fun (info: System.Diagnostics.ProcessStartInfo) -> + info.FileName <- System.IO.Path.GetFullPath fakePath + info.Arguments <- sprintf "%s --fsiargs -d:FAKE %s \"%s\"" args fsiargs script + info.WorkingDirectory <- workingDirectory + let setVar k v = + info.EnvironmentVariables.[k] <- v + for (k, v) in environmentVars do + setVar k v + setVar "MSBuild" msBuildExe + setVar "GIT" Git.CommandHelper.gitPath + setVar "FSI" fsiPath) + +/// Run the given buildscript with FAKE.exe +let executeFAKEWithOutput workingDirectory script fsiargs envArgs = + let exitCode = + ExecProcessWithLambdas + (fakeStartInfo script workingDirectory "" fsiargs envArgs) + TimeSpan.MaxValue false ignore ignore + System.Threading.Thread.Sleep 1000 + exitCode + +// Documentation +let buildDocumentationTarget fsiargs target = + trace (sprintf "Building documentation (%s), this could take some time, please wait..." target) + let exit = executeFAKEWithOutput "docs/tools" "generate.fsx" fsiargs ["target", target] + if exit <> 0 then + failwith "generating reference documentation failed" + () + +Target "GenerateReferenceDocs" (fun _ -> + buildDocumentationTarget "-d:RELEASE -d:REFERENCE" "Default" +) + +let generateHelp' fail debug = + let args = + if debug then "--define:HELP" + else "--define:RELEASE --define:HELP" + try + buildDocumentationTarget args "Default" + traceImportant "Help generated" + with + | e when not fail -> + traceImportant "generating help documentation failed" + +let generateHelp fail = + generateHelp' fail false + +Target "GenerateHelp" (fun _ -> + DeleteFile "docs/content/release-notes.md" + CopyFile "docs/content/" "RELEASE_NOTES.md" + Rename "docs/content/release-notes.md" "docs/content/RELEASE_NOTES.md" + + DeleteFile "docs/content/license.md" + CopyFile "docs/content/" "LICENSE.txt" + Rename "docs/content/license.md" "docs/content/LICENSE.txt" + + generateHelp true +) + +Target "GenerateHelpDebug" (fun _ -> + DeleteFile "docs/content/release-notes.md" + CopyFile "docs/content/" "RELEASE_NOTES.md" + Rename "docs/content/release-notes.md" "docs/content/RELEASE_NOTES.md" + + DeleteFile "docs/content/license.md" + CopyFile "docs/content/" "LICENSE.txt" + Rename "docs/content/license.md" "docs/content/LICENSE.txt" + + generateHelp' true true +) + +Target "KeepRunning" (fun _ -> + use watcher = !! "docs/content/**/*.*" |> WatchChanges (fun changes -> + generateHelp' true true + ) + + traceImportant "Waiting for help edits. Press any key to stop." + + System.Console.ReadKey() |> ignore + + watcher.Dispose() +) + +Target "GenerateDocs" DoNothing + +let createIndexFsx lang = + let content = """(*** hide ***) +// This block of code is omitted in the generated HTML documentation. Use +// it to define helpers that you do not want to show in the documentation. +#I "../../../bin" + +(** +F# Project Scaffold ({0}) +========================= +*) +""" + let targetDir = "docs/content" lang + let targetFile = targetDir "index.fsx" + ensureDirectory targetDir + System.IO.File.WriteAllText(targetFile, System.String.Format(content, lang)) + +Target "AddLangDocs" (fun _ -> + let args = System.Environment.GetCommandLineArgs() + if args.Length < 4 then + failwith "Language not specified." + + args.[3..] + |> Seq.iter (fun lang -> + if lang.Length <> 2 && lang.Length <> 3 then + failwithf "Language must be 2 or 3 characters (ex. 'de', 'fr', 'ja', 'gsw', etc.): %s" lang + + let templateFileName = "template.cshtml" + let templateDir = "docs/tools/templates" + let langTemplateDir = templateDir lang + let langTemplateFileName = langTemplateDir templateFileName + + if System.IO.File.Exists(langTemplateFileName) then + failwithf "Documents for specified language '%s' have already been added." lang + + ensureDirectory langTemplateDir + Copy langTemplateDir [ templateDir templateFileName ] + + createIndexFsx lang) +) + +// -------------------------------------------------------------------------------------- +// Release Scripts + +Target "ReleaseDocs" (fun _ -> + let tempDocsDir = "temp/gh-pages" + CleanDir tempDocsDir + Repository.cloneSingleBranch "" (gitHome + "/" + gitName + ".git") "gh-pages" tempDocsDir + + CopyRecursive "docs/output" tempDocsDir true |> tracefn "%A" + StageAll tempDocsDir + Git.Commit.Commit tempDocsDir (sprintf "Update generated documentation for version %s" release.NugetVersion) + Branches.push tempDocsDir +) + +#load "paket-files/build/fsharp/FAKE/modules/Octokit/Octokit.fsx" +open Octokit + +Target "Release" (fun _ -> + let user = + match getBuildParam "github-user" with + | s when not (String.IsNullOrWhiteSpace s) -> s + | _ -> getUserInput "Username: " + let pw = + match getBuildParam "github-pw" with + | s when not (String.IsNullOrWhiteSpace s) -> s + | _ -> getUserPassword "Password: " + let remote = + Git.CommandHelper.getGitResult "" "remote -v" + |> Seq.filter (fun (s: string) -> s.EndsWith("(push)")) + |> Seq.tryFind (fun (s: string) -> s.Contains(gitOwner + "/" + gitName)) + |> function None -> gitHome + "/" + gitName | Some (s: string) -> s.Split().[0] + + StageAll "" + Git.Commit.Commit "" (sprintf "Bump version to %s" release.NugetVersion) + Branches.pushBranch "" remote (Information.getBranchName "") + + Branches.tag "" release.NugetVersion + Branches.pushTag "" remote release.NugetVersion + + // release on github + createClient user pw + |> createDraft gitOwner gitName release.NugetVersion (release.SemVer.PreRelease <> None) release.Notes + // TODO: |> uploadFile "PATH_TO_FILE" + |> releaseDraft + |> Async.RunSynchronously +) + +Target "BuildPackage" DoNothing + +// -------------------------------------------------------------------------------------- +// Run all targets by default. Invoke 'build ' to override + +Target "All" DoNothing + +"AssemblyInfo" + ==> "Build" + ==> "CopyBinaries" + ==> "RunTests" + ==> "GenerateReferenceDocs" + ==> "GenerateDocs" +#if MONO +#else + =?> ("SourceLink", Pdbstr.tryFind().IsSome ) +#endif + ==> "NuGet" + ==> "BuildPackage" + ==> "All" + =?> ("ReleaseDocs",isLocalBuild) + +"GenerateHelp" + ==> "GenerateReferenceDocs" + ==> "GenerateDocs" + +"GenerateHelpDebug" + ==> "KeepRunning" + +"Clean" + ==> "Release" + +"BuildPackage" + ==> "PublishNuget" + ==> "Release" + +"ReleaseDocs" + ==> "Release" + +RunTargetOrDefault "All" diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..c5de482 --- /dev/null +++ b/build.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash + +set -eu + +cd "$(dirname "$0")" + +PAKET_BOOTSTRAPPER_EXE=.paket/paket.bootstrapper.exe +PAKET_EXE=.paket/paket.exe +FAKE_EXE=packages/build/FAKE/tools/FAKE.exe + +FSIARGS="" +FSIARGS2="" +OS=${OS:-"unknown"} +if [ "$OS" != "Windows_NT" ] +then + # Can't use FSIARGS="--fsiargs -d:MONO" in zsh, so split it up + # (Can't use arrays since dash can't handle them) + FSIARGS="--fsiargs" + FSIARGS2="-d:MONO" +fi + +run() { + if [ "$OS" != "Windows_NT" ] + then + mono "$@" + else + "$@" + fi +} + +yesno() { + # NOTE: Defaults to NO + read -p "$1 [y/N] " ynresult + case "$ynresult" in + [yY]*) true ;; + *) false ;; + esac +} + +set +e +run $PAKET_BOOTSTRAPPER_EXE +bootstrapper_exitcode=$? +set -e + +if [ "$OS" != "Windows_NT" ] && + [ $bootstrapper_exitcode -ne 0 ] && + [ $(certmgr -list -c Trust | grep X.509 | wc -l) -le 1 ] && + [ $(certmgr -list -c -m Trust | grep X.509 | wc -l) -le 1 ] +then + echo "Your Mono installation has no trusted SSL root certificates set up." + echo "This may result in the Paket bootstrapper failing to download Paket" + echo "because Github's SSL certificate can't be verified. One way to fix" + echo "this issue would be to download the list of SSL root certificates" + echo "from the Mozilla project by running the following command:" + echo "" + echo " mozroots --import --sync" + echo "" + echo "This will import over 100 SSL root certificates into your Mono" + echo "certificate repository." + echo "" + if yesno "Run 'mozroots --import --sync' now?" + then + mozroots --import --sync + else + echo "Attempting to continue without running mozroots. This might fail." + fi + # Re-run bootstrapper whether or not the user ran mozroots, because maybe + # they fixed the problem in a separate terminal window. + run $PAKET_BOOTSTRAPPER_EXE +fi + +run $PAKET_EXE restore + +[ ! -e build.fsx ] && run $PAKET_EXE update +[ ! -e build.fsx ] && run $FAKE_EXE init.fsx +run $FAKE_EXE "$@" $FSIARGS $FSIARGS2 build.fsx + diff --git a/docs/content/index.fsx b/docs/content/index.fsx new file mode 100644 index 0000000..495f14e --- /dev/null +++ b/docs/content/index.fsx @@ -0,0 +1,67 @@ +(*** hide ***) +// This block of code is omitted in the generated HTML documentation. Use +// it to define helpers that you do not want to show in the documentation. +#I "../../bin" + +(** +Higher +====================== + +Documentation + +
+ +Example +------- + +This example demonstrates using a function defined in this sample library. + +*) +#r "Higher.dll" +open Higher + +printfn "hello = %i" <| Library.hello 0 + +(** +Some more info + +Samples & documentation +----------------------- + +The library comes with comprehensible documentation. +It can include tutorials automatically generated from `*.fsx` files in [the content folder][content]. +The API reference is automatically generated from Markdown comments in the library implementation. + + * [Tutorial](tutorial.html) contains a further explanation of this sample library. + + * [API Reference](reference/index.html) contains automatically generated documentation for all types, modules + and functions in the library. This includes additional brief samples on using most of the + functions. + +Contributing and copyright +-------------------------- + +The project is hosted on [GitHub][gh] where you can [report issues][issues], fork +the project and submit pull requests. If you're adding a new public API, please also +consider adding [samples][content] that can be turned into a documentation. You might +also want to read the [library design notes][readme] to understand how it works. + +The library is available under Public Domain license, which allows modification and +redistribution for both commercial and non-commercial purposes. For more information see the +[License file][license] in the GitHub repository. + + [content]: https://github.com/fsprojects/Higher/tree/master/docs/content + [gh]: https://github.com/fsprojects/Higher + [issues]: https://github.com/fsprojects/Higher/issues + [readme]: https://github.com/fsprojects/Higher/blob/master/README.md + [license]: https://github.com/fsprojects/Higher/blob/master/LICENSE.txt +*) diff --git a/docs/content/tutorial.fsx b/docs/content/tutorial.fsx new file mode 100644 index 0000000..2501c0e --- /dev/null +++ b/docs/content/tutorial.fsx @@ -0,0 +1,19 @@ +(*** hide ***) +// This block of code is omitted in the generated HTML documentation. Use +// it to define helpers that you do not want to show in the documentation. +#I "../../bin" + +(** +Introducing your project +======================== + +Say more + +*) +#r "Higher.dll" +open Higher + +Library.hello 0 +(** +Some more info +*) diff --git a/docs/files/img/logo-template.pdn b/docs/files/img/logo-template.pdn new file mode 100644 index 0000000000000000000000000000000000000000..52606f5701c62c79bca692489b4d19150329a5e3 GIT binary patch literal 15052 zcmd^l3A7Vcw)VZs*bWGaASfUx_Uj<2%!$I)RHc$sWvoiYH( z$r7Civr>vs-mv-H;J*5Sx`76r#yC(909tL|hCx(Ol=9hzK~k!ijrS?!n8AHn0`vvS zfXl(;t;*%aLn%1KC{LbRVM8EmRJlV^*kz=Z2dg#W#RC9h6+}H{#A+`BIV_|Bl|Gep zxnz!Fq1sE7f>SZ7tWXd=O4VeuQi&4pP(A>?Iy@8r31^Bn#WW~i(GYe$sm@iRnncOz zKua-;T~|yicQ2L!LD)(K;AoN!K$I_lRuIU>5KbEtP}`_X)!=jyrUXUABPK(kqBFw~ zN$Fxlyc7!-H5oxr3(AL{9LPH0G=>GDObA6p%ms5eV#jd=h9u=@4|5O*2@nXT>?x38 z*h)F0N2#I^;_0HgREmVdx`aoq(IXLc%)!AFO^0zkRgAbS33ZZIsVrq#rB*{I8UO<( z1WU$Bu`y&yZ#iFLnn8ByCR}3n3G7`~KdXuSI)zY|~G7?5C6g4K3YE#T^4X9Kq zK!@Wl$Y|#=K2Q-Dj=|v&uVch&Mhl``#uqFWRc4hYug6FoR$!s9la*~{nH5d#kJOEYk5(E_~4nhzJL@OZbg;Yoy)MG9ymsa@n`<xB{s56T#pf-uzK;#?s+Ye2vd!$5e% zUD2BpX$wpF(vI5uC=_Dy6|>s!bXHV`pc9OF6){6Lkx4-?igbQvM_W-1y_YczfnXt9GhSEv9f zA09WU)j0_ji&O|U;tnU|!vjbF51s39wT3vajPszOT#~Us z!5T6kP|WG#DNce*CQXj8YXQs+ zHzItx1Yju4x+%`eV>pyUp@K%ssA)#Pcu;{m2;rz1baAmD$4EGYg)45ts@2D1fSt^g zy)tA)3@8B;6;rGN^O)0zLy;QxYz40ui|_%f4slrvZqDpwLI#gmDpfI4v|LuJlfj_C z%Kk(U;5kh?N#PD1;F8g<~Zd3Mo=FCKx`X^)lIDwunX8AnJ;yIUg)jAOh2H=k$o3 z36PwO+YxszqxDgGP;FMrPBpJ_&S>e*?p0`$ObSG5<(1)DERipO(v5v4};H!Ce_NCQJIZqR4SFy8LF5I zq9#9Hz~V8*?rAi%kBr51@kp$K%O>6&!Z94Qvlyz_-JH{v3kPt5NjcMnLX37;6f>z) z$z~~J^GOzik<_Itl|Vw52LKltU@O%EV3JftokmjmQP2aEoQMM{&L6>yS#Jb4O3F;M zDwz_J?m(cTmI~R7->=pIlvkl#*6MT-GOnUk@v@=hjO22e3|*4qpoYZdJfcB^umpH$ zF;#H}fTWEwn=M|AY^MG8XhkK)3eH?Q9ZYBev&-q!8T4M+4Oz=(vk3aYl0ov@lQ~N^ zQ$@k3o#aX>KrU3|q(2^usiK;&9!fg3ISl|9WTV?wi2Ai6f{08A_Tagct?D-=5f_$_ z!WLSz;c9&}kwlCvVnqn6ZAw45)~^uIOU_upVlufMmT(@* zrLr7>h15cNRjSor6PM=;=sFVzhGIt-28C*6OL5P0DlXDq4 zCTP<|b&(v;leD8!v8a=7+DFrDDy5I+a=MBPYKjH54JfBE4{PFaobeLcc)*qhLR3;0 z*5$)Cvzj%!APml+l$Zg_L7FW}UO^L$!sVD1@p(Pvm;-bLa=}75`nWWcbJ6{yUL9! zu|S&7ILcWb!W;#ZVg$LyzZasMG=Ud+I%dtgZDH2o1j8a}tXAwQ9gl;6&k>-R0-FmO zEVPg;;%QFG*}Vh|GX)$sfV?Xn1u|Y;3@rdsIp#NdEbzlgJlyVT)FR5?-TG zBWEd_8&`!5o~(jR3=boAGOqEtxkOrsDu^=?YOBSQHCBx|4@8J!9JGsimsOCl3R4PT zri3*UjQXUAs%Vl(Td=6F7!6J|rZZZ+fYL85<0+KlHW$fz?8TG^&aif-c^&Ds^O~X=Z~=@5 zO>jXa05M>;tkE8KW+guk`OvC2V}xQ3jF)2wc8Cduf}lpS z31OIrQPzm_VV@SPTAXPioX^0 zNkmgo6|2TEI2uHX79t#1qC`+*E0+~v3WCid>tQayd#OGSp$lSmjN90(VJ1&oUU<^YTF8Zj9*#zIUk zV3h?xWj9s1pho2fDNR{tEihVhDUWI_T8o%KOvXwj3DtrVwKZup@IV&jGhVZ`h{bI< znWfzlfyFe6`YQ^8Lp&KKN|GB#A)i?ZZGu1q@eqn%w#VXOwbhCtfkId<(?HNqD5l;J zu6m_pSww-9lZ(X&RW9!Lo1{=EXQAXEnpHM55hfcEqzWY&3nki+!h!`GYJniP6OLJF zXNhA&MbR&6g=p;i`S=7PIKe7W)#n60grGpsV+hB} zdPJWn;!&{_HZm1KPZX5c)G1nnI+@iGq?1BIcADlxWL zq87EHav_f=Trm@0aBx`MoU-87Tt$FQyj7iW8}kC8PT@sK*$>-e2&U|acvlgjb+ICc!d=qDt%bg=xVVV@yd~ z6i%UV4Dm>M3*(7-RaF;Mg$$OGTW9qO9Pc3h*MdvQ4P+5V8E%!$Wkt1G;dDC02~LQfZZ22_z2WP3OZ8&aUlh} ztfxFqQSY{wc?mK`vU-k%(+;hK@s@nq8OCg3Z^VO?S2KZQ99V*BMd%?;%891jeC3H!|5;W)`D30U+m@A}VGL|dgCL9dp zqWVD0Wn#6Nk{L+SB|?sQa#c#DFQ@Za<=nyyDf=PHz-T#=;1eVpLcCf4^{5doC+VVK z*%HXQgbY=U%X&b;Xg~pAHI>bmVZBaQE{nztr}qbeun(4^YE76(K%N|$<{&5$3Kc!B z1ZfIXQV9bWkp#a#DN-Q{=PfoARu&-Yu})rFa6;r+g`MOvVMh97YfwQ)I!MN(hJT6~aw|fDlbdVOm=( zQ(;IWVIe=v7cEYh#X#0Z=zMvE(xgfXpJ7Wh>_WVxM$$sYm^-Ws6w_|M;&-eeI7h{D zCK!OTQ3tExVglwSSV6!wkdAZYy_7PoBvSO3gDxWKOd!Po0~LCZ z#^VBf3IKoz$zl|54;y&ByW%j47Aem7G_klZW@R#AC=RFyLZ+$`C7WFCND2z8X*nRK zO&Z9~RVi;VtN17z8$i$yV-u66s=Ov>6A!r%yAQ#Mbh26oOfe~Laf9}_LkjAW zaJnea`hs!>00lfQNv&oKXe1#7I1~pc4ws~Y9HVoHz(oo^0Z??W#A9)rN-t}a{jy(U zB&$}h4btY(lHVJNa0$^;$q`0-C8g*P(dC1BF5#y@Ckzsj*6F1R8Y)!`0Tqv3Fa#v4 zA&U~MKV&r#B{A$O6{{6>$|C>;ADUo6b0KWw6OjU7RM^Q?D_Sb-N``$Qcg4jaHdDdi z!lAHM%cUIFOh{IawP?z~lkS)f@e?JE$V)c810oPCXG9AK6~dCREe!Y(lZ)_Jd`KoA zp*(CQA~@}3<%j{b$lhuOFS5A+rlNg(s7Ux2mCG2@Xq?d^t_f8f%321KZe>GcP-JL| zryxzSobUx5MY!jN>@=QG=M9MA=XI6O~n|AhM`ae4y%HWOoEJ+W2`q) z6m&vW2{O@`rzU&GpYgkwJke5;6*Zw)v2_kk+AY{( zl;{;?Fa)DcyC5k>Q{%DcWYz~zHJ){H&9yaD#QwFKv9xWj|2)nz2_?0tTtKCd-21Wvbgi$%xhJCV)M{z%> z^+(7I8Pp~t*$krzlvN79M8%DjbtoOQD%&i-Aq7>Wv?0z^74KL`t2JpZlyF0;NJW8o z3erZ5TAzr-H4zb_F#?b1f^s$)Bzz&WF@RXZsjMInjs(eg3?VZXqv9HU0yd=pfRF4c8COgHXQJ;T zvY0ATDj-Ix;(;`PEvm9ZTLOit(2@?6zsA+ww*QRWo+I_XeW(l|2~Bt)t-G)#Fknu2oh zQ8v)|oPeV?SIS-Wk{D-ac z(-ZDkARZ}tNXnV_B^2y}MyFgMLUb4dV{}0mDwtAEG{HG#X9cjJhb1dMO<5BCe$1>K=mii&1BG~R$sP-m9#qFGt3Yu?Iot!w2AAS! z6BHTNyTZyrK)$5mNGM?i{V`JUM?neY!}c7@2i;EIo$`cOEX~@KqexHC&vFS@*qKU` zDbYczgT5rEQO;eRu#HMpqJC@GY?Pv*sF;vKh%M!I8X*qKF?m#E=rX~>Hc>6vQ*spL zc-o?&vk}Chg)NvVh_ZZvGMLgZ5{@E(Q|olaG6Lw&o9*7HMqjZT$ZCm=r~(M=5)s$| zhhc{jn>&>3iJb+NbVJ3OS5RKt_A{8W)l|a&sKJvg+ssjhagYs}&CszJSXB zMG<6h-#+SwLF%8AQ|h0yUJZ5i%3odGb>*tvYuBweDTUWhvN_3?m%Owz&_+t+fIdIx zyndVV8qfzSW+cUr49?L-Ngy)=`uL0S3`@CaIhg0@+~8a>lWAKce%Ehk=BZ+q&PnZ* zhTpNGjTH-dkxsO`k!@?+nvH9BBM;Z{A8EJFMUfUfw4@w?NF*ZBS+TB7UER$$*LVFj zX?HDQ=VnEz#z=<_x8t&?bRGE9{14UtREP4)DJ3N-X*_YDgU-yUPgbPzLWYh1S{T4Ud;QuA@VMB)1 zn6K-2vr=sS>DN(_Rb9unO3}9V`ahRhtxvlGDJZJB!zu`*Toa^f1X~k!r(eAg*(%-T zSM}13jA$E${C}$F8@i~K9cx(V*j_1Wv#3p{O>NMBr>53)Uu|$0}#=d`KSMGvH}TCIayEoS|BMW{8ww!8H=Lm1lKrqtEH4576s zlv{^T2;Ue%`FDYzMzAv08`RGHOs&&zs2SVcq0~*kqGnd8v{EzwOikh7Cu%orJ6tpH zH>jTanQE8cP&Ku?^WRfdru09hdPi-2)|O94Wl`02>{=`CR*K)<+D$2c;~k*9K>ykx z{`wyx{(HOF>K$rhbo;dl2U#gg7FrE?tAi*A`2sCSEG@Pdi$ap5=sQ{)Rlj(STW-8) zbsV?ec)sC2e(L!PiB@yd=HdThJk_tp_Wxtp8s_f&^%wY!Y1E`q-=V|(zizrQcx(Av z0PI^L@kzjU}ysnplR-`b&<^3bujQvA}Pk5Xw{ zqx^ryRm~E&k1Lo+_zG?M|C)!8;%LDe4Wi1M7qVpLr)rIfRz~ixjag&lKa)!hI=^w^ z?L@_gCg`>zMdkpdv5jK5f1`2_oy{wInoOSJYC^63es)}a6zkrxZ;fJ2QvbcIYmjM^ zQ;t#pW4zG5<~kIPZ)KGX1;sIfk}OHI&lgBaNlABX6@@3CpzCY?q|HA|s8C;jQ;%OO zzZJTz>aNM+XN9-xr^w`Yzeug)14_NV{(9TpiUIoHeBTPPR^v5dL|um(wc1r*gL&&( z=wGYV@Lt2xZ&dzJt)+(jn%dj_UMbqQPOXpj#@Kb&>$fXo*Tz@c>gsC?qm`tpR;#U$ z|3Gp;t)-7rw32*SdH9K>{vRa2{1wTzHIV-g7lzWabz!uvA@#q4b`4h@ly${ODWkq) ziWL2=p;m_koumbUPAJVC>+5Uauj79bRek%Kpj+da+WqE#4kuqTCLKZL6vCw{5rFa9g$hb#)*1e!fHNLz}u2AJr>9`__;8aOd+!R|54f_=mmq|L^rt zd+SFn+iq}NGo`K9ZRuaJGvnbG?)tRLlfFLQLHtcmJwE;MJ~JQhdYh^3F5PwDvCe0{ZE0zLW%P*la<7?}`fNV6v-9}2SN3jr<8sdf`pqky zJvVnNW(9AU(X_gi*fZ8$yTo$LpP?v%dse(~(Zo4+`C|EJayr`jIv za{T+Z^ewONT5Yy{X*fWfIMw0k9qX^`eeLEE?Oq!P{Y4!7^4BdhUmNkYL$&3e6)Re9 zi%!(9z^|-%y2ZbbdBO2+lsWa)>m%RVw0wi=hi=y%{&W8o!-iZRJD}Tl;^o;F%5AU3 zugu?L9((yQ!*z&i)80DsnZqr!nOFLZZr`~p`~A`O{U7SzgL!q@*DIc)OQ-#3KTeMh zf1#ds=kHlQzjw@$URNg{e7x(I_wC-l_trCS9G&y+HvR?i_)V8Tj(<3Ow||EG&ZvFA zJ3C|LjQzJ~K5uSVl&}x8g_t(vI%=oWAAXilc76;Cf-aUfy*q zvtLN9Amt}ihZnTW+jaJt(_Lm$^O!Mzo3Yq%>ew{-)uoG`4ods(=hyF9djFBBGb|0Z zo#*!M690HQUR{p{in14n0R2IY5$uS2JMclPkcVD92mI}7(QU@y-Q1b z77gBE+^*)N!w+`vW*s+tVs=ve@WeNNT)*){uBqEb*MVLKJtyQ9U!EE<7+}`%LxtZqZk#XqHaekZvlD z-TGiD-}S(<3;#;4b>b^~P`$@IJJPxBubS-*e?I|gyL>w?;XF3($D{wYq?5Bh(X?z5 zcw*Jo!t}w5J2^LQUA3fIiafD)$e9hj9@zKb)l0=qx}5pY_{PVz+n2tvQp{C0PT8|` z!uj_v?A#PRxt4siZJrf$ewh=GFO_Lh-)h+8hdV_btccr~=uk^k# za&f22-+^7;9VW83lF54pDf$j#jFa!bb#j8hiB`s%Y6(6uYSU$tw* z$s>>K2CnVpKi{!#R2vyP@X^x?KC1SdvvZT%yI{x38HhOIVD87I%=bUIj*cIFb;`TV z#Y^{mnB4#6!P^haW)^mA**o>N)u;Nd>@_<*sruN0=Dnl(dWK(n9@#c!=J2&co_yf= zkz1a7d*K5s?yfx5c-%f{$dwDtw~W62myfTUPp;c@F_5`q?4(aRzP;yVBj0@D5w`lb zH^wj5KW1-2OSgYE%<<~M(LDj%$1m%Kqk9Z%w!fjG2TZtrU3+oB`TKv^6+PNA?BpZ+ z`~$kZy<_CG!K2?`>H*S1!>7=PIKfk9qd%`;#nqC{*_(i`_ zpDkWJVbavqV&sucLs##;`K{hf_jUTJxZuE}ADS1x_wL4~*Q@o*4-5;hI{2*o+-Ej% zbFbL#-!9+&=)RZwFM42m!)C*`LjNr@Hl|1si4_DT3Gfi)@`8w0V3M@Lqwe_t4b)?PY) zbpNhzmM0o|cYmUT^T3Q-C%-%5N@E>5IW}Sq*znD$ho0;bX%3xU`(hUhS+~67>Z`Ms zWnURI|5~oj^3J#6gWIL)J4QYBWbpG5%a`44yn3*1O0<@xe6Z*7Qe(<5tpTZxOkA6dR(N@x*yqTQe0KNBm@Idb2$7cVY6_WrDcz``x% zCsnI9MhH5+X%({8wAL@AV7NKQl zFJ-MXY&mvv&Zf&RTIPPOX+-W-t-kokg(bt>(?*`8q}O+}_+H$8=eco1_jd2^c~xH2 zIB3ANt-yfKH{2t(KSRHK`1FI~lr~oi`=;cmRZWi`WmH%H1^{#BH{Q2r7b%XM`b6(0 zeB--6&e_p$^3S7~?zd0WU0S(*$L;X69>W%GJ((DP_;37?z87x(NWs?S)Mr=LA5ONs z-Q>Np`RMh3*;;*JVdEZuH}<6E`7duiGBWq4mf#=G_no_X&3y-&Q;V7yR%_u|Z@ z-eEIN)Gxif!m?@3`qCKw_=5EV-u9jNo#WmOJ9o`8pBU3}Yfty_X0*$hslwuh!Oibo ziaxvaN%P4sXKiRY^!>L(&aaxZc=+?fcYo3NP5!}+-Ns!{f7s~n`MhrQ+Ouo^^ss%t zVdcrylLDH|U!mjgA)0FU_FJ1%C)c;1C=b;PnNdCQ`kd^}p*i!$tqsTCFLWL;;;-LZ z_Uw9o)0r7B9)EpVcIWicz0|gqi7}l=3_s34tNG?)+Bo@}i^R0E_S0)0Ke7A{%lcz8 zneM&4_j#H*mpIQnS!mp&Uj4U4ldidch`xKte9_SDp8bDb{OqY?J74eh?1PI(%~`_j zI6v@E-AC5xqh24+qYLiogs#6nXkz7o^UH=jX+GN$Xqr8>G;1Ap;qvDCKfkvN*?Mru z)8_9#p4V;R%)kPEt#Q_A%eo!=7p)g!nS9r!GfTbNKTY;&*|TBJ)eBvl@W$!rwp&^@ zU!F`{%D%L@IsDFjyT?3m?zDUUq-pwc=dGVTak5PZ@sjS$wN6}9*UM0k4R7yg81>%S z{O6H|PxZ;B@a$5TqZ;<|+>uS~wt3!q`T1)Te%MuR_Yrh<*qz7wU7FsYA26=rkh^8p zsa@T=x9hTF8#8?U#KuMBs%x6lR~MZdv2*wX3(6D!mZB2d7d`maq#vGHGi$}P@hwfW z_e>emQq4>nc4o)Q=}7b5k^43VN2J&7i&L-XE#i}X*=yO|SI#zHnO0e{dg9Kd+mF2P zz0Tk5%CIe;4&Kl`J@nhlpRto(+Bx*|rAw~#dTr3w*lzgs#C2H# z(d;E)?4E8rZ_R8d4ys!>;-UQNql-E$zWwbr+sw$sPV<+gT6W$N|2N>S0UMBGD~DaY zzuR4d#SO+0r#F86@kdE=$?9S3<+jBmcWytAUSpdcZg%eJX&*Ne500LDdgS~D--(sY z)GgCgLT2PVM{L7WgWsP=t@|!FZT-rF7l~8mco%N7tYI6CC+>+padR{c78_ zcinRjgt|ZZ9sEIC>z(A}iN?R*)aHYsYwK>dcHjQQ%^xH>lRJk3F{5sBTb=cewe=sQ zbRTeUogOdtNN;MH|LWQEmeBb@g;$RBns-$4Y>_I6IXnIM>>ZnDPrEWU<=AE3tu!~CJI#M`0(#}n?5#(ke(!uU)!6Rh ztj^n$kN2E?`3J)pe#@q|;%ym9>b+|6jvnNE`!daZg<`PZ?pO9W7ESi08-{mJgFTmC z-aO&zjO~XFy-m|~OD25Vn0jXWmeg!#?;f*4y4}Cuu5?v%!#nL%ePREyp*myeH){v_ z-<-QD3>Khv4wmSZ1ZxGUFh*`z(2&(Gg<^V~MeIyaBAzxT{*#@vo6&6eh4 zCtF(l{RY^d=(%s+;gdtIiF0>Pn%x6AHf~w-!s30=S6wTXbodt%qGYU^jPw3ltK!lZn_djRYWna>8 z#?r5+rb(LHBR4zM`_i5sFHf8XqAhNOPUmWA)%w5!9Bey1LMxAW2--E#M5pE*DI z;+)Pcj5Yhrg~=D^b#8uPRB~V2Wv9j1ntq2zYWKhQod|zrnF*hp-1E}4jU$WQ9=!H> zuX*POy*Byfm5aJwY${)wCS2L|RlN6+AHz>&e;l&$k1>BgvN1IVzxykvv-bzttMeul zBaip{O8udFjA8#1=#n^rMjFX!1 z`BA8+E%oN)PaE5;JU!dEV!>p4|MQ*qjJ-bhqtQK5iE|>>b7+7FeJ@%a; zw@hfW^1H?*p9hw9&Mt0a=<#Jcm+-0mrrnhp+uvBe@cv_W@7#QGojB;Z^!|-Q{ZF?w z2zwuG@%9`LeOzI0&i-q2ZyUIv(C_|6sb$e^UAt!HRC@1vt?eIs{L8L!#uW0D{kijB z?%kpvWbW5JJ@s4X1m$WZUM~8kT)9ZAR)qruU5Kdztqq z+r1aQoXTze PmMh&#w`1pP#_E3ov+rLx literal 0 HcmV?d00001 diff --git a/docs/files/img/logo.png b/docs/files/img/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..8a2b81b9eb60b9bd48e50daed8ab02a46ee4992f GIT binary patch literal 1581 zcmXw3dr%W+5Wl3S(FfL4WtA!Y%7hEfB!WB|b8zRyCiVIVTx zNzPm!kts^~A#+bmdOVOCle8;y)vowVJNH%WRc?h-Y9RnDXcF+bn z*li~;306aP%Y%y_0u+mAh&qS~58j$LH~q#G z(!AI7P7v@a;K4anPh1DRbFD{?CC`k4tH9`WpLUy8FJIZ&Ii50G%=g!EI`_@yHw=Ec z=jKi23khOhIw@uVsAYKr)=cunp1k<@G3BZAvlAk{wfW3t?TVfRh!}mVDil!J0WWlD z3%}LeE(WSh7j%QSNvLtZ*W;c&roXfii2sXub+u%OU|XU6CK6!I2&}+Z!O@)L}$~ZX;#W(qagHT z71H?4SU^yr9j8p=&f*U4Zmu~(<4}3Q;KhMCgk57OH1o0=vDbDeJlhOG@UYRlcj+!l zR&kXeG(uh~Dg6&&i4w;(*$!rzE7IKcSk_Fcs{m23@{D*jhIsVppUhHARrKQ8LG?u4 zBN}BZGVz8uIDpY5SyqBT1w7x8>wYC08jB2q```#kF{@YG6v&H^H%LlYy`>Lm6d!~= zwvWFNr!zcrtVJc)x(<`~S%g(V^^`H3H-vys4vLDLzqg6~&tQRa|$R z*ku3G;X1JCE!AJi>b+b~bDZw6)-bzsN%$Mo<7GMX4DNP3ZJGzWN+Ev!2aC;4_T+%$ zO5<9xc7at4lw5qc=hm2AI>c`C+NDdVQ31~@o&`(4jfL2awpVp;-xQ5cP|s2$A$C3V zMAwipYc*(j1|)}^U}J6}h-^9xa^P53gAXH*EXSG*^dYYk z3FpKeKWJt&mSHllRRb)R9CL6@hh~O%{5`-~ce$*}_97@*b9fu}#3XxVg~|?omiifh+Hsmj>=l_z6AzHj%P zh9}7VaJVZ*w+<*dGr}Yk37JWCJiXKDFk<0meCm1n1*b!Zh2hMsABR7*2lEj%fRFdH zVWE_cr~s-Bsw)*rRP*%zFHtiJ&C|ofM4a4m VXWV0Pq6A; +// otherwise, use the current 'output' directory. +#if RELEASE +let root = website +#else +let root = "file://" + (__SOURCE_DIRECTORY__ @@ "../output") +#endif + +// Paths with template/source/output locations +let bin = __SOURCE_DIRECTORY__ @@ "../../bin" +let content = __SOURCE_DIRECTORY__ @@ "../content" +let output = __SOURCE_DIRECTORY__ @@ "../output" +let files = __SOURCE_DIRECTORY__ @@ "../files" +let templates = __SOURCE_DIRECTORY__ @@ "templates" +let formatting = __SOURCE_DIRECTORY__ @@ "../../packages/build/FSharp.Formatting/" +let docTemplate = "docpage.cshtml" + +// Where to look for *.csproj templates (in this order) +let layoutRootsAll = new System.Collections.Generic.Dictionary() +layoutRootsAll.Add("en",[ templates; formatting @@ "templates" + formatting @@ "templates/reference" ]) +subDirectories (directoryInfo templates) +|> Seq.iter (fun d -> + let name = d.Name + if name.Length = 2 || name.Length = 3 then + layoutRootsAll.Add( + name, [templates @@ name + formatting @@ "templates" + formatting @@ "templates/reference" ])) + +// Copy static files and CSS + JS from F# Formatting +let copyFiles () = + CopyRecursive files output true |> Log "Copying file: " + ensureDirectory (output @@ "content") + CopyRecursive (formatting @@ "styles") (output @@ "content") true + |> Log "Copying styles and scripts: " + +let binaries = + let manuallyAdded = + referenceBinaries + |> List.map (fun b -> bin @@ b) + + let conventionBased = + directoryInfo bin + |> subDirectories + |> Array.map (fun d -> d.FullName @@ (sprintf "%s.dll" d.Name)) + |> List.ofArray + + conventionBased @ manuallyAdded + +let libDirs = + let conventionBasedbinDirs = + directoryInfo bin + |> subDirectories + |> Array.map (fun d -> d.FullName) + |> List.ofArray + + conventionBasedbinDirs @ [bin] + +// Build API reference from XML comments +let buildReference () = + CleanDir (output @@ "reference") + MetadataFormat.Generate + ( binaries, output @@ "reference", layoutRootsAll.["en"], + parameters = ("root", root)::info, + sourceRepo = githubLink @@ "tree/master", + sourceFolder = __SOURCE_DIRECTORY__ @@ ".." @@ "..", + publicOnly = true,libDirs = libDirs ) + +// Build documentation from `fsx` and `md` files in `docs/content` +let buildDocumentation () = + + // First, process files which are placed in the content root directory. + + Literate.ProcessDirectory + ( content, docTemplate, output, replacements = ("root", root)::info, + layoutRoots = layoutRootsAll.["en"], + generateAnchors = true, + processRecursive = false) + + // And then process files which are placed in the sub directories + // (some sub directories might be for specific language). + + let subdirs = Directory.EnumerateDirectories(content, "*", SearchOption.TopDirectoryOnly) + for dir in subdirs do + let dirname = (new DirectoryInfo(dir)).Name + let layoutRoots = + // Check whether this directory name is for specific language + let key = layoutRootsAll.Keys + |> Seq.tryFind (fun i -> i = dirname) + match key with + | Some lang -> layoutRootsAll.[lang] + | None -> layoutRootsAll.["en"] // "en" is the default language + + Literate.ProcessDirectory + ( dir, docTemplate, output @@ dirname, replacements = ("root", root)::info, + layoutRoots = layoutRoots, + generateAnchors = true ) + +// Generate +copyFiles() +#if HELP +buildDocumentation() +#endif +#if REFERENCE +buildReference() +#endif diff --git a/docs/tools/templates/template.cshtml b/docs/tools/templates/template.cshtml new file mode 100644 index 0000000..1ae4a1b --- /dev/null +++ b/docs/tools/templates/template.cshtml @@ -0,0 +1,58 @@ + + + + + @Title + + + + + + + + + + + + + + + +
+ +
+
+
+ @RenderBody() +
+
+ F# Project + +
+
+
+ Fork me on GitHub + + diff --git a/lib/README.md b/lib/README.md new file mode 100644 index 0000000..11cdd7a --- /dev/null +++ b/lib/README.md @@ -0,0 +1,11 @@ +This file is in the `lib` directory. + +Any **libraries** on which your project depends and which are **NOT managed via NuGet** should be kept **in this directory**. +This typically includes custom builds of third-party software, private (i.e. to a company) codebases, and native libraries. + +--- +NOTE: + +This file is a placeholder, used to preserve directory structure in Git. + +This file does not need to be edited. diff --git a/paket.dependencies b/paket.dependencies new file mode 100644 index 0000000..c0c79d7 --- /dev/null +++ b/paket.dependencies @@ -0,0 +1,18 @@ +source https://nuget.org/api/v2 + +nuget FSharp.Core redirects: force + +group Build + source https://nuget.org/api/v2 + + nuget SourceLink.Fake + nuget FAKE + nuget FSharp.Formatting + + github fsharp/FAKE modules/Octokit/Octokit.fsx + +group Test + source https://nuget.org/api/v2 + + nuget NUnit ~> 2 + nuget NUnit.Runners ~> 2 \ No newline at end of file diff --git a/paket.lock b/paket.lock new file mode 100644 index 0000000..cb29758 --- /dev/null +++ b/paket.lock @@ -0,0 +1,32 @@ +NUGET + remote: https://www.nuget.org/api/v2 + FSharp.Core (4.0.0.1) - redirects: force + +GROUP Build +NUGET + remote: https://www.nuget.org/api/v2 + FAKE (4.41.6) + FSharp.Compiler.Service (2.0.0.6) + FSharp.Formatting (2.14.4) + FSharp.Compiler.Service (2.0.0.6) + FSharpVSPowerTools.Core (>= 2.3 < 2.4) + FSharpVSPowerTools.Core (2.3) + FSharp.Compiler.Service (>= 2.0.0.3) + Microsoft.Bcl (1.1.10) - framework: net10, net11, net20, net30, net35, net40, net40-full + Microsoft.Bcl.Build (>= 1.0.14) + Microsoft.Bcl.Build (1.0.21) - import_targets: false, framework: net10, net11, net20, net30, net35, net40, net40-full + Microsoft.Net.Http (2.2.29) - framework: net10, net11, net20, net30, net35, net40, net40-full + Microsoft.Bcl (>= 1.1.10) + Microsoft.Bcl.Build (>= 1.0.14) + Octokit (0.23) + Microsoft.Net.Http - framework: net10, net11, net20, net30, net35, net40, net40-full + SourceLink.Fake (1.1) +GITHUB + remote: fsharp/FAKE + modules/Octokit/Octokit.fsx (889bda9367dfb24f9abb524165a0dbe2cdd86252) + Octokit (>= 0.20) +GROUP Test +NUGET + remote: https://www.nuget.org/api/v2 + NUnit (2.6.4) + NUnit.Runners (2.6.4) diff --git a/src/Higher.Core/Algebra.fs b/src/Higher.Core/Algebra.fs deleted file mode 100644 index 6e7cc58..0000000 --- a/src/Higher.Core/Algebra.fs +++ /dev/null @@ -1,5 +0,0 @@ -namespace Higher.Core - -type Algebra<'F, 'A> = App<'F, 'A> -> 'A - -type CoAlgebra<'F, 'A> = 'A -> App<'F, 'A> \ No newline at end of file diff --git a/src/Higher.Core/Higher.Core.fsproj b/src/Higher.Core/Higher.Core.fsproj deleted file mode 100644 index 5374b54..0000000 --- a/src/Higher.Core/Higher.Core.fsproj +++ /dev/null @@ -1,116 +0,0 @@ - - - - - Debug - AnyCPU - {C979A279-D345-469C-84B9-DACCFDE18FFD} - Library - Higher.Core - Higher.Core - v4.5 - 4.3.1.0 - Higher.Core - - - true - full - false - false - bin\Debug\ - DEBUG;TRACE - 3 - bin\Debug\Higher.Core.XML - - - pdbonly - true - true - bin\Release\ - TRACE - 3 - bin\Release\Higher.Core.XML - - - 11 - - - - - $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets - - - - - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - True - - - - \ No newline at end of file diff --git a/src/Higher.Core/Adjunction.fs b/src/Higher/Adjunction.fs similarity index 68% rename from src/Higher.Core/Adjunction.fs rename to src/Higher/Adjunction.fs index 013c5d4..c42fef1 100644 --- a/src/Higher.Core/Adjunction.fs +++ b/src/Higher/Adjunction.fs @@ -1,28 +1,28 @@ -namespace Higher.Core +namespace Higher [] -type Adjunction<'F, 'G>(func : Functor<'F>, g : Functor<'G>) = +type Adjunction<'F, 'G>(func : Functor<'F>, g : Functor<'G>) = abstract Unit : 'A -> App<'G, App<'F, 'A>> abstract CoUnit : App<'F, App<'G, 'A>> -> 'A - member self.LeftAdjunct (f : App<'F, 'A> -> 'B) (v : 'A) : App<'G, 'B> = + member self.LeftAdjunct (f : App<'F, 'A> -> 'B) (v : 'A) : App<'G, 'B> = g.Map f (self.Unit v) - member self.RightAdjunct (f : 'A -> App<'G, 'B>) (v : App<'F, 'A>) : 'B = + member self.RightAdjunct (f : 'A -> App<'G, 'B>) (v : App<'F, 'A>) : 'B = self.CoUnit <| func.Map f v member self.F : Functor<'F> = func member self.G : Functor<'G> = g -type AdjunctionMonad<'F, 'G>(adj : Adjunction<'F, 'G>) = +type AdjunctionMonad<'F, 'G>(adj : Adjunction<'F, 'G>) = inherit Monad>() - override self.Return (x : 'A) : App3 = + override self.Return (x : 'A) : App3 = Compose.Inj <| Comp (adj.Unit x) - override self.Bind (c : App3, k : 'A -> App3) = + override self.Bind (c : App3, k : 'A -> App3) = let comp = adj.G.Map (adj.RightAdjunct (Compose.Run << k)) (Compose.Run c) comp |> Comp |> Compose.Inj -type AdjunctionComonad<'F, 'G>(adj : Adjunction<'F, 'G>) = +type AdjunctionComonad<'F, 'G>(adj : Adjunction<'F, 'G>) = inherit Comonad>() - override self.Extract<'A> (w:App3) : 'A = - w |> Compose.Run |> adj.CoUnit + override self.Extract<'A> (w:App3) : 'A = + w |> Compose.Run |> adj.CoUnit override self.Extend<'A, 'B> (f:App3 -> 'B) (w:App3) : App3 = - let comp = adj.F.Map (adj.LeftAdjunct (f << Compose.Inj << Comp)) (Compose.Run w) - comp |> Comp |> Compose.Inj \ No newline at end of file + let comp = adj.F.Map (adj.LeftAdjunct (f << Compose.Inj << Comp)) (Compose.Run w) + comp |> Comp |> Compose.Inj diff --git a/src/Higher/Algebra.fs b/src/Higher/Algebra.fs new file mode 100644 index 0000000..f446a99 --- /dev/null +++ b/src/Higher/Algebra.fs @@ -0,0 +1,5 @@ +namespace Higher + +type Algebra<'F, 'A> = App<'F, 'A> -> 'A + +type CoAlgebra<'F, 'A> = 'A -> App<'F, 'A> diff --git a/src/Higher/App.config b/src/Higher/App.config new file mode 100644 index 0000000..7c7a547 --- /dev/null +++ b/src/Higher/App.config @@ -0,0 +1,10 @@ + + + + + + True + + + + diff --git a/src/Higher.Core/Applicative.fs b/src/Higher/Applicative.fs similarity index 54% rename from src/Higher.Core/Applicative.fs rename to src/Higher/Applicative.fs index 1de0f5d..4927d7b 100644 --- a/src/Higher.Core/Applicative.fs +++ b/src/Higher/Applicative.fs @@ -1,12 +1,10 @@ -namespace Higher.Core +namespace Higher -// Applicative Class +/// Applicative Class [] -type Applicative<'F>() = - inherit Functor<'F>() - override self.Map f func = +type Applicative<'F>() = + inherit Functor<'F>() + override self.Map f func = self.Apply (self.Pure f) func abstract Pure<'T> : 'T -> App<'F, 'T> abstract Apply<'T, 'R> : App<'F, 'T -> 'R> -> App<'F, 'T> -> App<'F, 'R> - - diff --git a/src/Higher.Core/Arrow.fs b/src/Higher/Arrow.fs similarity index 91% rename from src/Higher.Core/Arrow.fs rename to src/Higher/Arrow.fs index 116b159..6827d23 100644 --- a/src/Higher.Core/Arrow.fs +++ b/src/Higher/Arrow.fs @@ -1,4 +1,4 @@ -namespace Higher.Core +namespace Higher [] type Arrow<'F>() = @@ -15,4 +15,4 @@ type Arrow<'F>() = member self.Split (a : App2<'F, 'A, 'B>) (b : App2<'F, 'C, 'D>) : App2<'F, 'A * 'C, 'B * 'D> = self.First a |> self.Compose (self.Second b) member self.Fanout (a : App2<'F, 'A, 'B>) (b : App2<'F, 'A, 'C>) : App2<'F, 'A, 'B * 'C> = - self.Split a b |> self.MapIn (fun a -> a,a) \ No newline at end of file + self.Split a b |> self.MapIn (fun a -> a,a) diff --git a/src/Higher.Core/Category.fs b/src/Higher/Category.fs similarity index 58% rename from src/Higher.Core/Category.fs rename to src/Higher/Category.fs index 30162f4..7a52d72 100644 --- a/src/Higher.Core/Category.fs +++ b/src/Higher/Category.fs @@ -1,7 +1,7 @@ -namespace Higher.Core +namespace Higher -// Category Class +/// Category Class [] -type Category<'F>() = +type Category<'F>() = abstract Ident<'A> : unit -> App2<'F, 'A, 'A> - abstract Compose<'A, 'B, 'C> : App2<'F, 'A, 'B> -> App2<'F, 'B, 'C> -> App2<'F, 'A, 'C> \ No newline at end of file + abstract Compose<'A, 'B, 'C> : App2<'F, 'A, 'B> -> App2<'F, 'B, 'C> -> App2<'F, 'A, 'C> diff --git a/src/Higher.Core/Choice.fs b/src/Higher/Choice.fs similarity index 81% rename from src/Higher.Core/Choice.fs rename to src/Higher/Choice.fs index 88b1ecf..7873c14 100644 --- a/src/Higher.Core/Choice.fs +++ b/src/Higher/Choice.fs @@ -1,20 +1,20 @@ -namespace Higher.Core +namespace Higher -// Choice Monad type +/// Choice Monad type type Choice private () = static let token = new Choice() - static member Inj (value : Choice<'A,'B>) : App2 = + static member Inj (value : Choice<'A,'B>) : App2 = let app = new App(token, value) new App2<_, _, _>(AppToken.Token token, app) - static member Prj (app2 : App2) : Choice<'A, 'B> = + static member Prj (app2 : App2) : Choice<'A, 'B> = let app = app2.Apply(AppToken.Token token) :?> App app.Apply(token) :?> _ -// Choice Monad instance -type ChoiceMonad<'A>() = +/// Choice Monad instance +type ChoiceMonad<'A>() = inherit Monad>() with override self.Return x = Choice.Inj <| Choice2Of2 x - override self.Bind (m, f) = + override self.Bind (m, f) = match Choice.Prj m with | Choice2Of2 v -> f v | Choice1Of2 a -> Choice.Inj (Choice1Of2 a) diff --git a/src/Higher.Core/CoYoneda.fs b/src/Higher/CoYoneda.fs similarity index 71% rename from src/Higher.Core/CoYoneda.fs rename to src/Higher/CoYoneda.fs index 9531321..6319801 100644 --- a/src/Higher.Core/CoYoneda.fs +++ b/src/Higher/CoYoneda.fs @@ -1,41 +1,35 @@ -namespace Higher.Core +namespace Higher -type Lambda<'F, 'A, 'R> = +type Lambda<'F, 'A, 'R> = abstract Invoke<'B> : ('B -> 'A) -> App<'F, 'B> -> 'R -// type CoYoneda f α = ∃β. (β → α) * f β +/// type CoYoneda f α = ∃β. (β → α) * f β [] type CoYoneda<'F, 'A>() = - abstract Invoke<'R> : Lambda<'F, 'A, 'R> -> 'R + abstract Invoke<'R> : Lambda<'F, 'A, 'R> -> 'R -type CoYonedaConstr<'F, 'B, 'A>(f : 'B -> 'A, app : App<'F, 'B>) = +type CoYonedaConstr<'F, 'B, 'A>(f : 'B -> 'A, app : App<'F, 'B>) = inherit CoYoneda<'F, 'A>() - override self.Invoke lambda = + override self.Invoke lambda = lambda.Invoke f app type CoYoneda private () = static let token = new CoYoneda() - static member Inj (value : CoYoneda<'F, 'A>) : App2 = + static member Inj (value : CoYoneda<'F, 'A>) : App2 = let app = new App(token, value) new App2(AppToken.Token token, app) - static member Prj (app2 : App2) : CoYoneda<'F, 'A> = + static member Prj (app2 : App2) : CoYoneda<'F, 'A> = let app = app2.Apply(AppToken.Token token) :?> App app.Apply(token) :?> _ -type CoYonedaFunctor<'F>() = +type CoYonedaFunctor<'F>() = inherit Functor>() - - override self.Map (f : 'A -> 'B) (app : App2) = + + override self.Map (f : 'A -> 'B) (app : App2) = CoYoneda.Inj <| - (CoYoneda.Prj app).Invoke> + (CoYoneda.Prj app).Invoke> { new Lambda<'F, 'A, CoYoneda<'F, 'B>> with - member self.Invoke<'C> (k : 'C -> 'A) (app : App<'F, 'C>) = - new CoYonedaConstr<'F, 'C, 'B>(k >> f, app) :> CoYoneda<'F, 'B> } - - - - - - + member self.Invoke<'C> (k : 'C -> 'A) (app : App<'F, 'C>) = + new CoYonedaConstr<'F, 'C, 'B>(k >> f, app) :> CoYoneda<'F, 'B> } diff --git a/src/Higher.Core/Codensity.fs b/src/Higher/Codensity.fs similarity index 76% rename from src/Higher.Core/Codensity.fs rename to src/Higher/Codensity.fs index 8191fdd..2b588af 100644 --- a/src/Higher.Core/Codensity.fs +++ b/src/Higher/Codensity.fs @@ -1,33 +1,29 @@ -namespace Higher.Core +namespace Higher -// type C µ α = C (∀β. (α → µ β) → µ β) +/// type C µ α = C (∀β. (α → µ β) → µ β) type Codensity<'M, 'A> = abstract Invoke<'B> : ('A -> App<'M, 'B>) -> App<'M, 'B> type CodenT private () = static let token = new CodenT() - static member Inj (value : Codensity<'M, 'T>) : App2 = + static member Inj (value : Codensity<'M, 'T>) : App2 = let app = new App(token, value) new App2(AppToken.Token token, app) - static member Prj (app2 : App2) : Codensity<'M, 'T> = + static member Prj (app2 : App2) : Codensity<'M, 'T> = let app = app2.Apply(AppToken.Token token) :?> App app.Apply(token) :?> _ -type CodensityMonad<'M>() = +type CodensityMonad<'M>() = inherit Monad>() - override self.Return (x : 'A) = - CodenT.Inj <| + override self.Return (x : 'A) = + CodenT.Inj <| { new Codensity<'M, 'A> with member self.Invoke<'B> (f : 'A -> App<'M, 'B>) = f x } - override self.Bind (c : App2, k : 'A -> App2) = - CodenT.Inj <| + override self.Bind (c : App2, k : 'A -> App2) = + CodenT.Inj <| { new Codensity<'M, 'B> with member self.Invoke<'R> (f : 'B -> App<'M, 'R>) = - let c = CodenT.Prj c + let c = CodenT.Prj c c.Invoke (fun a -> let c' = CodenT.Prj (k a) in c'.Invoke f) } - - - - diff --git a/src/Higher.Core/Cofree.fs b/src/Higher/Cofree.fs similarity index 88% rename from src/Higher.Core/Cofree.fs rename to src/Higher/Cofree.fs index edeb517..dd154e8 100644 --- a/src/Higher.Core/Cofree.fs +++ b/src/Higher/Cofree.fs @@ -1,33 +1,35 @@ -namespace Higher.Core +namespace Higher /// Cofree comonad - an 'A stream with branching factor 'F. type Cofree<'F, 'A> = Cofree of 'A * App<'F, Cofree<'F, 'A>> type Cofree private () = - static let token = new Cofree() + static let token = new Cofree() static member Inj (value : Cofree<'F, 'A>) : App2 = let app = new App(token, value) - new App2(AppToken.Token token, app) + new App2(AppToken.Token token, app) static member Prj (app2 : App2) : Cofree<'F, 'A> = let app = app2.Apply(AppToken.Token token) :?> App app.Apply(token) :?> _ + type CofreeComonad<'F>(func : Functor<'F>) = inherit Comonad>() with - override self.Extract (c : App2) : 'A = + override self.Extract (c : App2) : 'A = let (Cofree(a,_)) = Cofree.Prj c in a override self.Extend (f : App2 -> 'B) (fa : App2) : App2 = - let (Cofree(a, ffa)) = Cofree.Prj fa + let (Cofree(_, ffa)) = Cofree.Prj fa let ffb = func.Map (fun fa -> self.Extend f (Cofree.Inj fa) |> Cofree.Prj) ffa Cofree.Cofree(f fa, ffb) |> Cofree.Inj + type Cofree with - + static member inline head (Cofree(a,_)) = a static member inline tail (Cofree(_,tl)) = tl - - static member toList (cofree : Cofree ) : 'A list = + + static member toList (cofree : Cofree ) : 'A list = let (Cofree(a, ffa)) = cofree in match Option.Prj ffa with | Some cofree -> a::(Cofree.toList cofree) @@ -35,5 +37,3 @@ type Cofree with static member ana (func : Functor<'F>) (f : 'A -> 'B) (g : 'A -> App<'F, 'A>) (a : 'A) : Cofree<'F, 'B> = Cofree.Cofree(f a, g a |> func.Map (Cofree.ana func f g)) - - diff --git a/src/Higher.Core/Comonad.fs b/src/Higher/Comonad.fs similarity index 92% rename from src/Higher.Core/Comonad.fs rename to src/Higher/Comonad.fs index 87a5f2e..86dbf86 100644 --- a/src/Higher.Core/Comonad.fs +++ b/src/Higher/Comonad.fs @@ -1,17 +1,18 @@ -namespace Higher.Core +namespace Higher -// Comonad Class +/// Comonad Class [] -type Comonad<'W>() = +type Comonad<'W>() = inherit Functor<'W>() override self.Map (f : 'A -> 'B) (func : App<'W, 'A>) = self.Extend (self.Extract >> f) func abstract Extract<'A> : App<'W, 'A> -> 'A abstract Extend<'A, 'B> : (App<'W, 'A> -> 'B) -> App<'W, 'A> -> App<'W, 'B> -// Generic comonad functions. + +/// Generic comonad functions. module Comonad = - + let duplicate (comonad : Comonad<'W>) (w : App<'W, 'A>) : App<'W, App<'W, 'A>> = comonad.Extend id w @@ -33,13 +34,12 @@ type ComonadZip<'W>() = inherit Comonad<'W>() abstract Apply : App<'W, 'A -> 'B> -> App<'W, 'A> -> App<'W, 'B> + module ComonadZip = - + let lift2 (comonad : ComonadZip<'W>) (f : 'A -> 'B -> 'C) (wa : App<'W, 'A>) (wb : App<'W, 'B>) : App<'W, 'C> = let wbc = comonad.Extend (comonad.Extract >> f) wa comonad.Apply wbc wb let zip (comonad : ComonadZip<'W>) (wa : App<'W, 'A>) (wb : App<'W, 'B>) : App<'W, 'A * 'B> = lift2 comonad (fun a b -> a,b) wa wb - - \ No newline at end of file diff --git a/src/Higher.Core/Compose.fs b/src/Higher/Compose.fs similarity index 82% rename from src/Higher.Core/Compose.fs rename to src/Higher/Compose.fs index 4122e66..562dde7 100644 --- a/src/Higher.Core/Compose.fs +++ b/src/Higher/Compose.fs @@ -1,10 +1,10 @@ -namespace Higher.Core +namespace Higher type Compose<'F, 'G, 'A> = Comp of App<'F, App<'G, 'A>> -type Compose private () = +type Compose private () = static let token = new Compose() - static member Inj (value : Compose<'F, 'G, 'A>) : App3 = + static member Inj (value : Compose<'F, 'G, 'A>) : App3 = let app = new App(token, value) let app2 = new App2(AppToken.Token token, app) new App3(AppToken, 'G>.Token app, app2) @@ -14,22 +14,19 @@ type Compose private () = let app2 = app3.Apply(token'') :?> App2 let app = app2.Apply(token') :?> App app.Apply(token) :?> _ - static member Run (app3 : App3) : App<'F, App<'G, 'A>> = + static member Run (app3 : App3) : App<'F, App<'G, 'A>> = let (Comp app) = Compose.Prj app3 in app -type ComposeFunctor<'F, 'G>(F : Functor<'F>, G : Functor<'G>) = +type ComposeFunctor<'F, 'G>(F : Functor<'F>, G : Functor<'G>) = inherit Functor>() - override self.Map (f : 'A -> 'B) (app : App3) : App3 = + override self.Map (f : 'A -> 'B) (app : App3) : App3 = Compose.Inj <| Comp (F.Map (G.Map f) (Compose.Run app)) - -type ComposeApplicative<'F, 'G>(F : Applicative<'F>, G : Applicative<'G>) = + +type ComposeApplicative<'F, 'G>(F : Applicative<'F>, G : Applicative<'G>) = inherit Applicative>() - override self.Pure (v : 'A) : App3 = + override self.Pure (v : 'A) : App3 = Compose.Inj <| Comp (F.Pure (G.Pure v)) override self.Apply (f : App, 'A -> 'B>) (app : App3) : App3 = Compose.Inj <| Comp (F.Apply (F.Map G.Apply (Compose.Run f)) (Compose.Run app)) - - - diff --git a/src/Higher.Core/Const.fs b/src/Higher/Const.fs similarity index 73% rename from src/Higher.Core/Const.fs rename to src/Higher/Const.fs index 9733a34..62dcfa0 100644 --- a/src/Higher.Core/Const.fs +++ b/src/Higher/Const.fs @@ -1,17 +1,16 @@ -namespace Higher.Core +namespace Higher type Const<'A, 'B> = C of 'A -type Const private () = +type Const private () = static let token = Const () static member Inj (value : Const<'A, 'B>) : App2 = App2(AppToken.Token token, value) static member Prj (app : App2) : Const<'A, 'B> = app.Apply(AppToken.Token token) :?> _ - + type ConstFunctor<'K>() = inherit Functor>() with - override self.Map (f : 'A -> 'B) (app : App2) : App2 = - let (C k) = app |> Const.Prj + override self.Map (_ : 'A -> 'B) (app : App2) : App2 = + let (C k) = app |> Const.Prj (C k) |> Const.Inj - diff --git a/src/Higher.Core/Cont.fs b/src/Higher/Cont.fs similarity index 75% rename from src/Higher.Core/Cont.fs rename to src/Higher/Cont.fs index 6171fe4..f727398 100644 --- a/src/Higher.Core/Cont.fs +++ b/src/Higher/Cont.fs @@ -1,24 +1,24 @@ -namespace Higher.Core +namespace Higher -// Continuation Monad type +/// Continuation Monad type type Cont<'R, 'T> = C of (('T -> 'R) -> 'R) + type Cont private () = static let token = new Cont() - static member Inj (value : Cont<'R, 'T>) : App2 = + static member Inj (value : Cont<'R, 'T>) : App2 = let app = new App(token, value) new App2(AppToken.Token token, app) - static member Prj (app2 : App2) : Cont<'R, 'T> = + static member Prj (app2 : App2) : Cont<'R, 'T> = let app = app2.Apply(AppToken.Token token) :?> App app.Apply(token) :?> _ - static member Run(cont : App2) = + static member Run(cont : App2) = let (C f) = Cont.Prj cont in f -// Continuation Monad instance -type ContMonad<'R>() = +/// Continuation Monad instance +type ContMonad<'R>() = inherit Monad>() with override self.Return x = Cont.Inj <| C (fun k -> k x) - override self.Bind (m, f) = - Cont.Inj <| C (fun k -> + override self.Bind (m, f) = + Cont.Inj <| C (fun k -> let contF = Cont.Run m contF (fun x -> Cont.Run (f x) k)) - diff --git a/src/Higher.Core/ContT.fs b/src/Higher/ContT.fs similarity index 69% rename from src/Higher.Core/ContT.fs rename to src/Higher/ContT.fs index 51a9192..59fd8c5 100644 --- a/src/Higher.Core/ContT.fs +++ b/src/Higher/ContT.fs @@ -1,10 +1,11 @@ -namespace Higher.Core +namespace Higher -// Continuation Monad Transformer type -type ContT<'R, 'M, 'T> = CT of (('T -> App<'M, 'R>) -> App<'M, 'R>) -type ContT private () = +/// Continuation Monad Transformer type +type ContT<'R, 'M, 'T> = CT of (('T -> App<'M, 'R>) -> App<'M, 'R>) + +type ContT private () = static let token = new ContT() - static member Inj (value : ContT<'R, 'M, 'T>) : App3 = + static member Inj (value : ContT<'R, 'M, 'T>) : App3 = let app = new App(token, value) let app2 = new App2(AppToken.Token token, app) new App3(AppToken, 'M>.Token app, app2) @@ -14,26 +15,25 @@ type ContT private () = let app2 = app3.Apply(token'') :?> App2 let app = app2.Apply(token') :?> App app.Apply(token) :?> _ - static member Run (contT : App3) = + static member Run (contT : App3) = let (CT cont) = ContT.Prj contT in cont - -// ContT Monad Transformer instance -type ContTMonadTrans<'R>() = +/// ContT Monad Transformer instance +type ContTMonadTrans<'R>() = inherit MonadTrans>() with - override self.Lift monad m = + override self.Lift monad m = ContT.Inj <| CT (fun k -> monad { let! x = m in return! k x }) -// ContT Monad instance -type ContTMonad<'R, 'M>(monad : Monad<'M>) = +/// ContT Monad instance +type ContTMonad<'R, 'M>(monad : Monad<'M>) = inherit Monad>() with override self.Return x = ContT.Inj <| CT (fun k -> monad { return! k x }) - override self.Bind (m, f) = + override self.Bind (m, f) = ContT.Inj <| CT (fun k -> - let cont = ContT.Run m - cont (fun x -> + let cont = ContT.Run m + cont (fun x -> monad { return! ContT.Run (f x) k - })) \ No newline at end of file + })) diff --git a/src/Higher.Core/Coproduct.fs b/src/Higher/Coproduct.fs similarity index 59% rename from src/Higher.Core/Coproduct.fs rename to src/Higher/Coproduct.fs index a0e148d..956fccc 100644 --- a/src/Higher.Core/Coproduct.fs +++ b/src/Higher/Coproduct.fs @@ -1,109 +1,112 @@ -namespace Higher.Core +namespace Higher type Coproduct<'F,'G,'A> = Cp of Choice,App<'G,'A>> -type Coproduct private () = +type Coproduct private () = static let token = new Coproduct() - static member Inj (value: Coproduct<'F,'G,'A>) : App3 = + static member Inj (value: Coproduct<'F,'G,'A>) : App3 = let app = new App(token,value) let app2 = new App2(AppToken.Token token, app) new App3(AppToken,'G>.Token app, app2) - static member Prj (app3: App3) : Coproduct<'F,'G,'A> = + static member Prj (app3: App3) : Coproduct<'F,'G,'A> = let token' = AppToken.Token token let token'' = AppToken,'G>.Token token' let app2 = app3.Apply(token'') :?> App2 let app = app2.Apply(token') :?> App app.Apply(token) :?> _ + [] -module Coproduct = +module Coproduct = - let inline coproduct - (f: App<'F,'A> -> 'B) - (g: App<'G,'A> -> 'B) + let inline coproduct + (f: App<'F,'A> -> 'B) + (g: App<'G,'A> -> 'B) (cp: App3) : 'B = match Coproduct.Prj cp with | Cp (Choice1Of2 x) -> f x | Cp (Choice2Of2 x) -> g x - let inline left - (fa: App<'F,'A>) - : App3 = + let inline left + (fa: App<'F,'A>) + : App3 = Coproduct.Inj << Cp << Choice1Of2 <| fa - let inline right - (ga: App<'G,'A>) - : App3 = + let inline right + (ga: App<'G,'A>) + : App3 = Coproduct.Inj << Cp << Choice2Of2 <| ga type CoproductFunctor<'F,'G> - (functorF: Functor<'F>, functorG: Functor<'G>) = - + (functorF: Functor<'F>, functorG: Functor<'G>) = + inherit Functor>() - override self.Map - (f: 'A -> 'B) - (app: App3) - : App3 = + override self.Map + (f: 'A -> 'B) + (app: App3) + : App3 = - Coproduct.coproduct - (Coproduct.left << functorF.Map f) - (Coproduct.right << functorG.Map f) + Coproduct.coproduct + (Coproduct.left << functorF.Map f) + (Coproduct.right << functorG.Map f) app type CoproductTraversable<'F,'G> - (travF: Traversable<'F>, travG: Traversable<'G>) = - + (travF: Traversable<'F>, travG: Traversable<'G>) = + inherit Traversable>() - override self.Traverse<'H, 'T, 'R> - (app : Applicative<'H>) - (f : 'T -> App<'H, 'R>) - (trav : App3) - : App<'H,App3> = + override self.Traverse<'H, 'T, 'R> + (app : Applicative<'H>) + (f : 'T -> App<'H, 'R>) + (trav : App3) + : App<'H,App3> = Coproduct.coproduct (app.Map Coproduct.left << travF.Traverse app f) (app.Map Coproduct.right << travG.Traverse app f) trav + type CoproductComonad<'F,'G> - (comonadF: Comonad<'F>, comonadG: Comonad<'G>) = + (comonadF: Comonad<'F>, comonadG: Comonad<'G>) = inherit Comonad>() - override self.Extend - (f: App3 -> 'B) - (cp:App3) + override self.Extend + (f: App3 -> 'B) + (cp:App3) : App3 = Coproduct.coproduct (Coproduct.left << comonadF.Extend (f << Coproduct.left)) (Coproduct.right << comonadG.Extend (f << Coproduct.right)) - cp + cp - override self.Extract - (cp: App3) - : 'A = + override self.Extract + (cp: App3) + : 'A = Coproduct.coproduct comonadF.Extract comonadG.Extract cp + type CoproductContraFunctor<'F,'G> - (contraF : ContraFunctor<'F>, contraG : ContraFunctor<'G>) = + (contraF : ContraFunctor<'F>, contraG : ContraFunctor<'G>) = inherit ContraFunctor>() - override self.ContraMap - (f : 'A -> 'B) + override self.ContraMap + (f : 'A -> 'B) (cp : App3) - : App3 = - Coproduct.coproduct + : App3 = + Coproduct.coproduct (Coproduct.left << contraF.ContraMap f) (Coproduct.right << contraG.ContraMap f) - cp \ No newline at end of file + cp diff --git a/src/Higher.Core/CoreTypes.fs b/src/Higher/CoreTypes.fs similarity index 71% rename from src/Higher.Core/CoreTypes.fs rename to src/Higher/CoreTypes.fs index 42330d4..1b5fefc 100644 --- a/src/Higher.Core/CoreTypes.fs +++ b/src/Higher/CoreTypes.fs @@ -1,41 +1,33 @@ -namespace Higher.Core +namespace Higher open System -// The basic idea of Type Defunctionalization is based on +// The basic idea of Type Defunctionalization is based on // https://ocamllabs.github.io/higher/lightweight-higher-kinded-polymorphism.pdf // OCaml implementation https://github.com/ocamllabs/higher -// Represents type application -// To ensure type-safety we use a secret token based control access policy. +/// Represents type application. +/// To ensure type-safety we use a secret token based control access policy. type App<'F, 'T> (token : 'F, value : obj) = - do + do if Object.ReferenceEquals(token, Unchecked.defaultof<'F>) then raise <| new System.InvalidOperationException("Invalid token") // Apply the secret token to have access to the encapsulated value member self.Apply(token' : 'F) = - if Object.ReferenceEquals(token, token') then - value + if Object.ReferenceEquals(token, token') then + value else raise <| new InvalidOperationException("Invalid token") type App2<'F, 'T1, 'T2> = App, 'T2> type App3<'F, 'T1, 'T2, 'T3> = App, 'T3> type App4<'F, 'T1, 'T2, 'T3, 'T4> = App, 'T4> -// A Singleton-like type for managing parameterized tokens -type AppToken<'App, 'R>() = - static let appTokenRef = ref Unchecked.defaultof> - static member Token (token : 'App) = +// A Singleton-like type for managing parameterized tokens +type AppToken<'App, 'R>() = + static let appTokenRef = ref Unchecked.defaultof> + static member Token (token : 'App) = if !appTokenRef = Unchecked.defaultof> then lock appTokenRef (fun () -> if !appTokenRef = Unchecked.defaultof> then appTokenRef := new App<'App, 'R>(token, Unchecked.defaultof<'R>) ) !appTokenRef - - - - - - - - diff --git a/src/Higher.Core/FFree.fs b/src/Higher/FFree.fs similarity index 76% rename from src/Higher.Core/FFree.fs rename to src/Higher/FFree.fs index 8f5d19d..2fbb4de 100644 --- a/src/Higher.Core/FFree.fs +++ b/src/Higher/FFree.fs @@ -1,23 +1,23 @@ -namespace Higher.Core +namespace Higher // http://okmij.org/ftp/Computation/free-monad.html [] -type FFree<'F, 'A>() = - abstract Invoke<'R> : FFreeUnPack<'F, 'A, 'R> -> 'R +type FFree<'F, 'A>() = + abstract Invoke<'R> : FFreeUnPack<'F, 'A, 'R> -> 'R -and FPure<'F, 'A>(a : 'A) = +and FPure<'F, 'A>(a : 'A) = inherit FFree<'F, 'A>() - override self.Invoke unpack = + override self.Invoke unpack = unpack.Invoke a -and FImpure<'F, 'B, 'A>(app : App<'F, 'B>, f : 'B -> App2) = +and FImpure<'F, 'B, 'A>(app : App<'F, 'B>, f : 'B -> App2) = inherit FFree<'F, 'A>() - override self.Invoke unpack = + override self.Invoke unpack = unpack.Invoke<'B>(app, f) and FFreeUnPack<'F, 'A, 'R> = - abstract Invoke : 'A -> 'R + abstract Invoke : 'A -> 'R abstract Invoke<'B> : App<'F, 'B> * ('B -> App2) -> 'R and FFree private () = @@ -25,19 +25,19 @@ and FFree private () = static member Inj (value : FFree<'F, 'T>) : App2 = let app = new App(token, value) new App2(AppToken.Token token, app) - static member Prj (app2 : App2) : FFree<'F, 'T> = + static member Prj (app2 : App2) : FFree<'F, 'T> = let app = app2.Apply(AppToken.Token token) :?> App app.Apply(token) :?> _ -// Freer Monad instance -type FreerMonad<'F>() = +/// Freer Monad instance +type FreerMonad<'F>() = inherit Monad>() with override self.Return x = FFree.Inj <| new FPure<'F, 'A>(x) override self.Bind (app : App2, f : 'A -> App2) : App2 = let monad = self let ffree = FFree.Prj app - ffree.Invoke> + ffree.Invoke> { new FFreeUnPack<'F, 'A, App2> with member self.Invoke (a : 'A) = f a - member self.Invoke<'C> (app : App<'F, 'C>, f' : 'C -> App2) = - FFree.Inj <| new FImpure<'F, 'C, 'B>(app, Monad.compose monad f' f) } \ No newline at end of file + member self.Invoke<'C> (app : App<'F, 'C>, f' : 'C -> App2) = + FFree.Inj <| new FImpure<'F, 'C, 'B>(app, Monad.compose monad f' f) } diff --git a/src/Higher.Core/FTLens.fs b/src/Higher/FTLens.fs similarity index 72% rename from src/Higher.Core/FTLens.fs rename to src/Higher/FTLens.fs index 59dfd16..26708da 100644 --- a/src/Higher.Core/FTLens.fs +++ b/src/Higher/FTLens.fs @@ -1,31 +1,29 @@ -namespace Higher.Core +namespace Higher -// Twan van Laarhoven's Functor transformer lenses // http://twanvl.nl/files/lenses-talk-2011-05-17.pdf -// type FTLens α β γ δ = ∀f . Functor f ⇒ (α → f β) → (γ → f δ) - - -type FTLens<'S, 'T, 'A, 'B> = +/// Twan van Laarhoven's Functor transformer lenses. +/// +/// type FTLens α β γ δ = ∀f . Functor f ⇒ (α → f β) → (γ → f δ) +type FTLens<'S, 'T, 'A, 'B> = abstract Apply<'F> : Functor<'F> -> ('A -> App<'F, 'B>) -> ('S -> App<'F, 'T>) - module Lens = let lens<'S, 'T, 'A, 'B> (get: 'S -> 'A) (set: 'B -> 'S -> 'T) : FTLens<'S, 'T, 'A, 'B> = { new FTLens<'S, 'T, 'A, 'B> with - override self.Apply<'F> (F : Functor<'F>) (f : 'A -> App<'F, 'B>) = - fun s -> F.Map (fun x -> set x s) (f (get s)) } + override self.Apply<'F> (F : Functor<'F>) (f : 'A -> App<'F, 'B>) = + fun s -> F.Map (fun x -> set x s) (f (get s))} let view<'S, 'T, 'A, 'B> (lens : FTLens<'S, 'T, 'A, 'B>) : 'S -> 'A = let F = new ConstFunctor<'A>() let f = lens.Apply F (C >> Const.Inj) - fun a -> let (C k) = Const.Prj (f a) in k + fun a -> let (C k) = Const.Prj (f a) in k - let over<'S, 'T, 'A, 'B> (lens : FTLens<'S, 'T, 'A, 'B>) (f : 'A -> 'B) : 'S -> 'T = + let over<'S, 'T, 'A, 'B> (lens : FTLens<'S, 'T, 'A, 'B>) (f : 'A -> 'B) : 'S -> 'T = let F = new IdentityFunctor() - let f' = lens.Apply F (f >> Id >> Identity.Inj) + let f' = lens.Apply F (f >> Id >> Identity.Inj) fun a -> let (Id v) = Identity.Prj (f' a) in v let set (lens : FTLens<'S, 'T, 'A, 'B>) (b : 'B) : 'S -> 'T = over lens (fun _ -> b) @@ -33,6 +31,3 @@ module Lens = let (>->) (l1: FTLens<_, _, _, _>) (l2: FTLens<_, _, _, _>) = { new FTLens<_, _, _, _> with override t.Apply F f = l1.Apply F (l2.Apply F f)} - - - diff --git a/src/Higher.Core/Fix.fs b/src/Higher/Fix.fs similarity index 77% rename from src/Higher.Core/Fix.fs rename to src/Higher/Fix.fs index d688237..07468d7 100644 --- a/src/Higher.Core/Fix.fs +++ b/src/Higher/Fix.fs @@ -1,18 +1,19 @@ -namespace Higher.Core +namespace Higher -/// Fix point. +/// Fixed point. type Fix<'F> = Fix of App<'F, Fix<'F>> type Fix private () = static let token = new Fix() - static member Inj (value : Fix<'F>) : App = + static member Inj (value : Fix<'F>) : App = new App<_, _>(token, value) - static member Prj (app : App) : Fix<'F> = + static member Prj (app : App) : Fix<'F> = app.Apply(token) :?> _ + [] module Fix = - + let inline un (Fix(f)) = f let rec cata (func : Functor<'F> ) (alg : Algebra<'F, 'A>) (fix : Fix<'F>) : 'A = @@ -27,7 +28,5 @@ module Fix = |> func.Map (ana func coalg) |> Fix.Fix - let hylo (func : Functor<'F>) (alg : Algebra<'F, 'B>) (coalg : CoAlgebra<'F, 'A>) (a : 'A) : 'B = + let hylo (func : Functor<'F>) (alg : Algebra<'F, 'B>) (coalg : CoAlgebra<'F, 'A>) (a : 'A) : 'B = ana func coalg a |> cata func alg - - \ No newline at end of file diff --git a/src/Higher.Core/Flip.fs b/src/Higher/Flip.fs similarity index 91% rename from src/Higher.Core/Flip.fs rename to src/Higher/Flip.fs index cffa873..ea30841 100644 --- a/src/Higher.Core/Flip.fs +++ b/src/Higher/Flip.fs @@ -1,10 +1,10 @@ -namespace Higher.Core +namespace Higher type Flip<'F, 'A, 'B> = F of App2<'F, 'B, 'A> -type Flip private () = +type Flip private () = static let token = new Flip() - static member Inj (value : Flip<'F, 'A, 'B>) : App3 = + static member Inj (value : Flip<'F, 'A, 'B>) : App3 = let app = new App(token, value) let app2 = new App2(AppToken.Token token, app) new App3(AppToken, 'A>.Token app, app2) @@ -14,6 +14,5 @@ type Flip private () = let app2 = app3.Apply(token'') :?> App2 let app = app2.Apply(token') :?> App app.Apply(token) :?> _ - static member Run (app3 : App3) : App2<'F, 'B, 'A> = + static member Run (app3 : App3) : App2<'F, 'B, 'A> = let (F app) = Flip.Prj app3 in app - diff --git a/src/Higher.Core/Free.fs b/src/Higher/Free.fs similarity index 73% rename from src/Higher.Core/Free.fs rename to src/Higher/Free.fs index aa31c51..0fcbde5 100644 --- a/src/Higher.Core/Free.fs +++ b/src/Higher/Free.fs @@ -1,23 +1,26 @@ -namespace Higher.Core +namespace Higher + +/// Free Monad type +type Free<'F, 'T> = + | Return of 'T + | Wrap of App<'F, Free<'F, 'T>> -// Free Monad type -type Free<'F, 'T> = Return of 'T | Wrap of App<'F, Free<'F, 'T>> type Free private () = static let token = new Free() static member Inj (value : Free<'F, 'T>) : App2 = let app = new App(token, value) new App2(AppToken.Token token, app) - static member Prj (app2 : App2) : Free<'F, 'T> = + static member Prj (app2 : App2) : Free<'F, 'T> = let app = app2.Apply(AppToken.Token token) :?> App app.Apply(token) :?> _ -// Free Monad instance -type FreeMonad<'F>(fuctorFree : Functor<'F>) = +/// Free Monad instance +type FreeMonad<'F>(fuctorFree : Functor<'F>) = inherit Monad>() with override self.Return x = Free.Inj <| Return x - override self.Bind (m, f) = + override self.Bind (m, f) = match Free.Prj m with | Return x -> f x - | Wrap func -> + | Wrap func -> let func' = fuctorFree.Map (fun m' -> Free.Prj <| self.Bind(Free.Inj m', f)) func Free.Inj <| Wrap func' diff --git a/src/Higher.Core/Fun.fs b/src/Higher/Fun.fs similarity index 62% rename from src/Higher.Core/Fun.fs rename to src/Higher/Fun.fs index e2ac53d..25047b1 100644 --- a/src/Higher.Core/Fun.fs +++ b/src/Higher/Fun.fs @@ -1,26 +1,26 @@ -namespace Higher.Core +namespace Higher -// Function type +/// Function type type Fun private () = static let token = new Fun() static member Inj (value : 'A -> 'B) : App2 = let app = new App(token, value) new App2(AppToken.Token token, app) - static member Prj (app2 : App2) : 'A -> 'B = + static member Prj (app2 : App2) : 'A -> 'B = let app = app2.Apply(AppToken.Token token) :?> App app.Apply(token) :?> _ -// Function Functor -type FunFunctor<'E>() = - inherit Functor>() +/// Function Functor +type FunFunctor<'E>() = + inherit Functor>() override self.Map (f : 'A -> 'B) (v : App2) : App2 = Fun.Inj <| fun e -> f (Fun.Prj v e) -// Function Category instance -type FunCategory() = +/// Function Category instance +type FunCategory() = inherit Category() with override self.Ident() = Fun.Inj id - override self.Compose f g = - Fun.Inj (fun x -> Fun.Prj g (Fun.Prj f x)) \ No newline at end of file + override self.Compose f g = + Fun.Inj (fun x -> Fun.Prj g (Fun.Prj f x)) diff --git a/src/Higher.Core/Functor.fs b/src/Higher/Functor.fs similarity index 83% rename from src/Higher.Core/Functor.fs rename to src/Higher/Functor.fs index 3ff6fbc..eb8e04d 100644 --- a/src/Higher.Core/Functor.fs +++ b/src/Higher/Functor.fs @@ -1,21 +1,21 @@ -namespace Higher.Core +namespace Higher -// Functor base classes +// Functor base classes [] -type Functor<'F>() = +type Functor<'F>() = abstract Map<'A, 'B> : ('A -> 'B) -> App<'F, 'A> -> App<'F, 'B> [] -type ContraFunctor<'F>() = +type ContraFunctor<'F>() = abstract ContraMap<'A, 'B> : ('A -> 'B) -> App<'F, 'B> -> App<'F, 'A> [] -type BiFunctor<'F>() = +type BiFunctor<'F>() = abstract BiMap<'A, 'B, 'C, 'D> : ('A -> 'B) -> ('C -> 'D) -> App2<'F, 'A, 'C> -> App2<'F, 'B, 'D> - member self.First<'A, 'B, 'C> (f : 'A -> 'B) (fac : App2<'F, 'A, 'C>) : App2<'F, 'B, 'C> = - self.BiMap f id fac - member self.Second<'A, 'B, 'C> (f : 'B -> 'C) (fab : App2<'F, 'A, 'B>) : App2<'F, 'A, 'C> = + member self.First<'A, 'B, 'C> (f : 'A -> 'B) (fac : App2<'F, 'A, 'C>) : App2<'F, 'B, 'C> = + self.BiMap f id fac + member self.Second<'A, 'B, 'C> (f : 'B -> 'C) (fab : App2<'F, 'A, 'B>) : App2<'F, 'A, 'C> = self.BiMap id f fab [] @@ -28,18 +28,18 @@ type ProFunctor<'F>() = module FunctorLaws = - + let identity (eq : App<'F, 'A> -> App<'F, 'A> -> bool) (func : Functor<'F>) (fa : App<'F, 'A>) = eq (func.Map id fa) fa + module BiFunctorLaws = - + let identity (eq : App2<'F, 'A, 'B> -> App2<'F, 'A, 'B> -> bool) (func : BiFunctor<'F>) (fab : App2<'F, 'A, 'B>) = eq (func.BiMap id id fab) fab + module ProFunctorLaws = - - let identity (eq : App2<'F, 'A, 'B> -> App2<'F, 'A, 'B> -> bool) (func : ProFunctor<'F>) (fab : App2<'F, 'A, 'B>) = - eq (func.DiMap id id fab) fab - \ No newline at end of file + let identity (eq : App2<'F, 'A, 'B> -> App2<'F, 'A, 'B> -> bool) (func : ProFunctor<'F>) (fab : App2<'F, 'A, 'B>) = + eq (func.DiMap id id fab) fab diff --git a/src/Higher/Higher.fsproj b/src/Higher/Higher.fsproj new file mode 100644 index 0000000..c711fc6 --- /dev/null +++ b/src/Higher/Higher.fsproj @@ -0,0 +1,185 @@ + + + + Debug + AnyCPU + 2.0 + a76feeb6-cf93-465d-8f57-d729c1fffe76 + Library + Higher + Higher + v4.0 + 4.3.0.0 + Higher + + + + true + full + false + false + .\bin\Debug + DEBUG;TRACE + 3 + .\bin\$(Configuration)\$(AssemblyName).xml + --warnon:1182 + + + pdbonly + true + true + .\bin\Release + TRACE + 3 + .\bin\$(Configuration)\$(AssemblyName).xml + --warnon:1182 + + + 11 + + + + + $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets + + + + + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ..\..\packages\FSharp.Core\lib\net20\FSharp.Core.dll + True + True + + + + + + + ..\..\packages\FSharp.Core\lib\net40\FSharp.Core.dll + True + True + + + + + + + ..\..\packages\FSharp.Core\lib\portable-net45+monoandroid10+monotouch10+xamarinios10\FSharp.Core.dll + True + True + + + + + + + ..\..\packages\FSharp.Core\lib\portable-net45+netcore45\FSharp.Core.dll + True + True + + + + + + + ..\..\packages\FSharp.Core\lib\portable-net45+netcore45+wp8\FSharp.Core.dll + True + True + + + + + + + ..\..\packages\FSharp.Core\lib\portable-net45+netcore45+wpa81+wp8\FSharp.Core.dll + True + True + + + + + + + ..\..\packages\FSharp.Core\lib\portable-net45+sl5+netcore45\FSharp.Core.dll + True + True + + + + + diff --git a/src/Higher.Core/Identity.fs b/src/Higher/Identity.fs similarity index 94% rename from src/Higher.Core/Identity.fs rename to src/Higher/Identity.fs index e4dfefc..0eeb563 100644 --- a/src/Higher.Core/Identity.fs +++ b/src/Higher/Identity.fs @@ -1,8 +1,8 @@ -namespace Higher.Core +namespace Higher type Identity<'A> = Id of 'A -type Identity private () = +type Identity private () = static let token = Identity() static member inline un (Id(a)) = a static member Inj (value : Identity<'A>) : App = @@ -12,7 +12,7 @@ type Identity private () = static member Run (app : App) : 'A = let (Id a) = Identity.Prj app a - + type IdentityFunctor() = inherit Functor() with override self.Map (f : 'A -> 'B) (app : App) : App = @@ -38,4 +38,4 @@ type IdentityComonad() = override self.Extract (app : App) : 'A = app |> Identity.Prj |> Identity.un override self.Extend (f : App -> 'B) (app : App) : App = - app |> f |> Id |> Identity.Inj \ No newline at end of file + app |> f |> Id |> Identity.Inj diff --git a/src/Higher.Core/Index.fs b/src/Higher/Index.fs similarity index 63% rename from src/Higher.Core/Index.fs rename to src/Higher/Index.fs index 8fa865f..108a425 100644 --- a/src/Higher.Core/Index.fs +++ b/src/Higher/Index.fs @@ -1,6 +1,6 @@ -namespace Higher.Core +namespace Higher -// Index-preserving Function +/// Index-preserving Function type Index<'F, 'G> = abstract Invoke<'A> : App<'F, 'A> -> App<'G, 'A> @@ -9,20 +9,19 @@ type Index private () = static member Inj (value : Index<'F, 'G>) : App2 = let app = new App(token, value) new App2(AppToken.Token token, app) - static member Prj (app2 : App2) : Index<'F, 'G> = + static member Prj (app2 : App2) : Index<'F, 'G> = let app = app2.Apply(AppToken.Token token) :?> App app.Apply(token) :?> _ - static member Run(index : App2) = + static member Run(index : App2) = Index.Prj index - -// Index-preserving Category instance -type IndexCategory() = +/// Index-preserving Category instance +type IndexCategory() = inherit Category() with - override self.Ident<'F>() = - Index.Inj { new Index<'F, 'F> with + override self.Ident<'F>() = + Index.Inj { new Index<'F, 'F> with member self.Invoke x = x } - override self.Compose f g = - Index.Inj ({ new Index<'A, 'C> with - member self.Invoke x = - (Index.Prj g).Invoke <| (Index.Prj f).Invoke x }) \ No newline at end of file + override self.Compose f g = + Index.Inj ({ new Index<'A, 'C> with + member self.Invoke x = + (Index.Prj g).Invoke <| (Index.Prj f).Invoke x }) diff --git a/src/Higher.Core/Kleisli.fs b/src/Higher/Kleisli.fs similarity index 81% rename from src/Higher.Core/Kleisli.fs rename to src/Higher/Kleisli.fs index c669b83..6db4dfa 100644 --- a/src/Higher.Core/Kleisli.fs +++ b/src/Higher/Kleisli.fs @@ -1,10 +1,10 @@ -namespace Higher.Core +namespace Higher type Kleisli<'M, 'A, 'B> = K of ('A -> App<'M, 'B>) -type Kleisli private () = +type Kleisli private () = static let token = new Kleisli() - static member Inj (value : Kleisli<'M, 'A, 'B>) : App3 = + static member Inj (value : Kleisli<'M, 'A, 'B>) : App3 = let app = new App(token, value) let app2 = new App2(AppToken.Token token, app) new App3(AppToken, 'A>.Token app, app2) @@ -14,20 +14,20 @@ type Kleisli private () = let app2 = app3.Apply(token'') :?> App2 let app = app2.Apply(token') :?> App app.Apply(token) :?> _ - static member Run (app : App3) = + static member Run (app : App3) = let (K f) = Kleisli.Prj app in f -type KleisliArrow<'M>(monad : Monad<'M>) = +type KleisliArrow<'M>(monad : Monad<'M>) = inherit Arrow>() - override self.Arr(f : ('A -> 'B)) : App2, 'A, 'B> = + override self.Arr(f : ('A -> 'B)) : App2, 'A, 'B> = Kleisli.Inj <| K (fun a -> monad { return f a }) - override self.First(f : App2, 'A, 'B>) : App2, 'A * 'C, 'B * 'C> = - let (K f') = Kleisli.Prj f + override self.First(f : App2, 'A, 'B>) : App2, 'A * 'C, 'B * 'C> = + let (K f') = Kleisli.Prj f Kleisli.Inj <| K (fun (a, c) -> monad { let! b = f' a in return (b, c) }) - override self.Ident<'A>() : App2, 'A, 'A> = + override self.Ident<'A>() : App2, 'A, 'A> = Kleisli.Inj <| K (fun a -> monad { return a }) - override self.Compose(f : App2, 'A, 'B>) (g : App2, 'B, 'C>) : App2, 'A, 'C> = + override self.Compose(f : App2, 'A, 'B>) (g : App2, 'B, 'C>) : App2, 'A, 'C> = let (K f') = Kleisli.Prj f let (K g') = Kleisli.Prj g - Kleisli.Inj <| K (Monad.compose monad f' g') \ No newline at end of file + Kleisli.Inj <| K (Monad.compose monad f' g') diff --git a/src/Higher.Core/LeftKan.fs b/src/Higher/LeftKan.fs similarity index 74% rename from src/Higher.Core/LeftKan.fs rename to src/Higher/LeftKan.fs index d63c394..073924d 100644 --- a/src/Higher.Core/LeftKan.fs +++ b/src/Higher/LeftKan.fs @@ -1,23 +1,24 @@ -namespace Higher.Core +namespace Higher -type Lambda<'G, 'H, 'A, 'R> = +type Lambda<'G, 'H, 'A, 'R> = abstract Invoke<'B> : (App<'G, 'B> -> 'A) -> App<'H, 'B> -> 'R -// type Lan g h α = ∃β. (g β → α) * h β -// type CoYoneda f a = Lan Id f a +/// type Lan g h α = ∃β. (g β → α) * h β +/// +/// type CoYoneda f a = Lan Id f a [] type Lan<'G, 'H, 'A>() = - abstract Invoke<'R> : Lambda<'G, 'H, 'A, 'R> -> 'R + abstract Invoke<'R> : Lambda<'G, 'H, 'A, 'R> -> 'R -type LanConstr<'G, 'H, 'B, 'A>(f : App<'G, 'B> -> 'A, app : App<'H, 'B>) = +type LanConstr<'G, 'H, 'B, 'A>(f : App<'G, 'B> -> 'A, app : App<'H, 'B>) = inherit Lan<'G, 'H, 'A>() - override self.Invoke lambda = + override self.Invoke lambda = lambda.Invoke f app type Lan private () = static let token = new Lan() - static member Inj (value : Lan<'G, 'H, 'A>) : App3 = + static member Inj (value : Lan<'G, 'H, 'A>) : App3 = let app = new App(token, value) let app2 = new App2(AppToken.Token token, app) new App3(AppToken, 'H>.Token app, app2) @@ -29,18 +30,12 @@ type Lan private () = app.Apply(token) :?> _ -type LanFunctor<'G, 'H>() = +type LanFunctor<'G, 'H>() = inherit Functor>() - - override self.Map (f : 'A -> 'B) (app : App3) = + + override self.Map (f : 'A -> 'B) (app : App3) = Lan.Inj <| - (Lan.Prj app).Invoke> + (Lan.Prj app).Invoke> { new Lambda<'G, 'H, 'A, Lan<'G, 'H, 'B>> with - member self.Invoke<'C> (k : App<'G, 'C> -> 'A) (app : App<'H, 'C>) = - new LanConstr<'G, 'H, 'C, 'B>(k >> f, app) :> Lan<'G, 'H, 'B> } - - - - - - + member self.Invoke<'C> (k : App<'G, 'C> -> 'A) (app : App<'H, 'C>) = + new LanConstr<'G, 'H, 'C, 'B>(k >> f, app) :> Lan<'G, 'H, 'B> } diff --git a/src/Higher.Core/Leibniz.fs b/src/Higher/Leibniz.fs similarity index 80% rename from src/Higher.Core/Leibniz.fs rename to src/Higher/Leibniz.fs index 2bbd2be..63f3e4c 100644 --- a/src/Higher.Core/Leibniz.fs +++ b/src/Higher/Leibniz.fs @@ -1,33 +1,35 @@ -namespace Higher.Core +namespace Higher -// Source +// Source // https://github.com/ocamllabs/higher/blob/master/examples/example-2-leibniz.ml // http://okmij.org/ftp/Haskell/LeibnizInjective.hs type Eq<'A, 'B> = abstract Invoke<'F> : App<'F, 'A> -> App<'F, 'B> + type Eq private () = static let token = new Eq() - static member Inj (value : Eq<'A, 'B>) : App2 = + static member Inj (value : Eq<'A, 'B>) : App2 = let app = new App(token, value) new App2(AppToken.Token token, app) - static member Prj (app2 : App2) : Eq<'A, 'B> = + static member Prj (app2 : App2) : Eq<'A, 'B> = let app = app2.Apply(AppToken.Token token) :?> App app.Apply(token) :?> _ + type AppEq<'A, 'B> = App2 -module Leibniz = - +module Leibniz = + let refl : unit -> AppEq<'A, 'A> = fun () -> Eq.Inj <| { new Eq<'A, 'A> with member self.Invoke<'F> (eq : App<'F, 'A>) = eq } let subst : AppEq<'A, 'B> -> App<'F, 'A> -> App<'F, 'B> = fun eq app -> - (Eq.Prj eq).Invoke app + (Eq.Prj eq).Invoke app let trans : AppEq<'A, 'B> -> AppEq<'B, 'C> -> AppEq<'A, 'C> = fun ab bc -> subst bc ab @@ -37,6 +39,5 @@ module Leibniz = x let symm : AppEq<'A, 'B> -> AppEq<'B, 'A> = fun ab -> - let flip = Flip.Inj <| F (refl ()) + let flip = Flip.Inj <| F (refl ()) Flip.Run <| subst ab flip - \ No newline at end of file diff --git a/src/Higher.Core/List.fs b/src/Higher/List.fs similarity index 58% rename from src/Higher.Core/List.fs rename to src/Higher/List.fs index 77b76db..3c5f279 100644 --- a/src/Higher.Core/List.fs +++ b/src/Higher/List.fs @@ -1,39 +1,37 @@ -namespace Higher.Core +namespace Higher -// List Monad type +/// List Monad type type List private () = - static let token = new List() - static member Inj (value : 'T list) : App = + static let token = new List() + static member Inj (value : 'T list) : App = new App<_, _>(token, value) - static member Prj (app : App) : 'T list = + static member Prj (app : App) : 'T list = app.Apply(token) :?> _ -// List Monad instance -type ListMonad() = +/// List Monad instance +type ListMonad() = inherit Monad() with override self.Return x = List.Inj [x] override self.Bind (m, f) = m - |> List.Prj - |> List.collect (fun v -> List.Prj (f v)) + |> List.Prj + |> List.collect (fun v -> List.Prj (f v)) |> List.Inj -// List Applicative Functor instance -type ListApplicative() = +/// List Applicative Functor instance +type ListApplicative() = inherit Applicative() with override self.Pure x = List.Inj [x] override self.Apply appF app = let fs, xs = List.Prj appF, List.Prj app xs |> List.zip fs |> List.map (fun (f, x) -> f x) |> List.Inj - - -// List Traversable instance -type ListTraversable() = +/// List Traversable instance +type ListTraversable() = inherit Traversable() with - override self.Map f func = + override self.Map f func = func |> List.Prj |> List.map f |> List.Inj - override self.Traverse<'F, 'T, 'R> (app : Applicative<'F>) (f : 'T -> App<'F, 'R>) (trav : App) = + override self.Traverse<'F, 'T, 'R> (app : Applicative<'F>) (f : 'T -> App<'F, 'R>) (trav : App) = let xs = trav |> List.Prj |> List.map f let appCons = app.Pure (fun (x : 'R) xs -> List.Inj (x :: (List.Prj xs))) - List.foldBack (fun appX appXs -> app.Apply (app.Apply appCons appX) appXs) xs (app.Pure (List.Inj [])) \ No newline at end of file + List.foldBack (fun appX appXs -> app.Apply (app.Apply appCons appX) appXs) xs (app.Pure (List.Inj [])) diff --git a/src/Higher.Core/ListT.fs b/src/Higher/ListT.fs similarity index 52% rename from src/Higher.Core/ListT.fs rename to src/Higher/ListT.fs index 2f2c638..ac8b207 100644 --- a/src/Higher.Core/ListT.fs +++ b/src/Higher/ListT.fs @@ -1,34 +1,34 @@ -namespace Higher.Core +namespace Higher -// ListT Monad Transformer type -type ListT<'M, 'T> = OT of App<'M, 'T list> -type ListT private () = +/// ListT Monad Transformer type +type ListT<'M, 'T> = LT of App<'M, 'T list> + +type ListT private () = static let token = new ListT() - static member Inj (value : ListT<'M, 'T>) : App2 = + static member Inj (value : ListT<'M, 'T>) : App2 = let app = new App(token, value) new App2(AppToken.Token token, app) - static member Prj (app2 : App2) : ListT<'M, 'T> = + static member Prj (app2 : App2) : ListT<'M, 'T> = let app = app2.Apply(AppToken.Token token) :?> App app.Apply(token) :?> _ - static member Run (listT : App2) = - let (OT appList) = ListT.Prj listT in appList - + static member Run (listT : App2) = + let (LT appList) = ListT.Prj listT in appList -// ListT Monad Transformer instance -type ListTMonadTrans() = +/// ListT Monad Transformer instance +type ListTMonadTrans() = inherit MonadTrans() with - override self.Lift monad m = - ListT.Inj <| OT (monad { let! x = m in return [x] }) + override self.Lift monad m = + ListT.Inj <| LT (monad { let! x = m in return [x] }) -// ListT Monad instance -type ListTMonad<'M>(monad : Monad<'M>) = +/// ListT Monad instance +type ListTMonad<'M>(monad : Monad<'M>) = inherit Monad>() with - override self.Return x = ListT.Inj <| OT (monad { return [x] }) - override self.Bind (m, f) = - ListT.Inj <| OT (monad { + override self.Return x = ListT.Inj <| LT (monad { return [x] }) + override self.Bind (m, f) = + ListT.Inj <| LT (monad { let! xs = ListT.Run m - let! yss = Monad.mapM monad (ListT.Run << f) xs + let! yss = Monad.mapM monad (ListT.Run << f) xs return List.concat yss }) diff --git a/src/Higher.Core/Monad.fs b/src/Higher/Monad.fs similarity index 78% rename from src/Higher.Core/Monad.fs rename to src/Higher/Monad.fs index f996fe7..40f9dfa 100644 --- a/src/Higher.Core/Monad.fs +++ b/src/Higher/Monad.fs @@ -1,12 +1,12 @@ -namespace Higher.Core -open System +namespace Higher +open System -// Monad Class +/// Monad Class [] -type Monad<'M>() = - inherit Applicative<'M>() +type Monad<'M>() = + inherit Applicative<'M>() override self.Pure x = self.Return x - override self.Apply appF app = + override self.Apply appF app = self { let! f = appF let! x = app @@ -15,20 +15,20 @@ type Monad<'M>() = abstract Return<'T> : 'T -> App<'M, 'T> abstract Bind<'T, 'R> : App<'M, 'T> * ('T -> App<'M, 'R>) -> App<'M, 'R> member self.ReturnFrom m = m - -// Generic Monad functions -module Monad = - - let compose (monad : Monad<'M>) (f : 'A -> App<'M, 'B>) (g : 'B -> App<'M, 'C>) : 'A -> App<'M, 'C> = + +/// Generic Monad functions +module Monad = + + let compose (monad : Monad<'M>) (f : 'A -> App<'M, 'B>) (g : 'B -> App<'M, 'C>) : 'A -> App<'M, 'C> = fun a -> monad { let! b = f a in return! g b } - let join (monad : Monad<'M>) (mm : App<'M, App<'M, 'T>>) : App<'M, 'T> = + let join (monad : Monad<'M>) (mm : App<'M, App<'M, 'T>>) : App<'M, 'T> = monad.Bind(mm, fun m -> m) let rec sequence (monad : Monad<'M>) (ms : App<'M, 'T> list) : App<'M, 'T list> = match ms with - | m :: ms -> + | m :: ms -> monad { let! x = m let! xs = sequence monad ms @@ -41,13 +41,10 @@ module Monad = let rec filterM (monad : Monad<'M>) (f : 'T -> App<'M, bool>) (xs : 'T list) : App<'M, 'T list> = match xs with - | x :: xs -> + | x :: xs -> monad { let! flag = f x let! xs' = filterM monad f xs return if flag then x :: xs' else xs' } - | [] -> monad { return [] } - - - + | [] -> monad { return [] } diff --git a/src/Higher.Core/MonadTrans.fs b/src/Higher/MonadTrans.fs similarity index 68% rename from src/Higher.Core/MonadTrans.fs rename to src/Higher/MonadTrans.fs index e6caf45..b745226 100644 --- a/src/Higher.Core/MonadTrans.fs +++ b/src/Higher/MonadTrans.fs @@ -1,8 +1,6 @@ -namespace Higher.Core +namespace Higher -// Monad Transformer Class +/// Monad Transformer Class [] type MonadTrans<'MT>() = abstract Lift<'M, 'T> : Monad<'M> -> App<'M, 'T> -> App2<'MT, 'M, 'T> - - diff --git a/src/Higher.Core/Monoid.fs b/src/Higher/Monoid.fs similarity index 75% rename from src/Higher.Core/Monoid.fs rename to src/Higher/Monoid.fs index 89916ff..aa9819f 100644 --- a/src/Higher.Core/Monoid.fs +++ b/src/Higher/Monoid.fs @@ -1,12 +1,12 @@ -namespace Higher.Core -open System +namespace Higher +open System -// Monoid class +/// Monoid class [] type Monoid<'T>() = abstract Empty : 'T abstract Append : 'T -> 'T -> 'T - + type Monoid private () = static let token = Monoid() static member Inj (m : 'T) : App2 = @@ -18,32 +18,32 @@ type Monoid private () = static member Run (app2: App2) : 'T = Monoid.Prj app2 -// Monoids are single object categories +/// Monoids are single object categories type MonoidCategory<'T>(m: Monoid<'T>) = - inherit Category() with + inherit Category() with override self.Ident<'A> () : App2 = Monoid.Inj m.Empty override self.Compose<'A, 'B, 'C> (ab:App2) (bc:App2) : App2 = m.Append (Monoid.Prj ab) (Monoid.Prj bc) |> Monoid.Inj - + // Basic Monoid instances type StringMonoid() = - inherit Monoid() with - override self.Empty = "" + inherit Monoid() with + override self.Empty = "" override self.Append x y = x + y type ListMonoid<'T>() = - inherit Monoid<'T list>() with - override self.Empty = [] + inherit Monoid<'T list>() with + override self.Empty = [] override self.Append xs ys = List.append xs ys type SeqMonoid<'T>() = - inherit Monoid>() with - override self.Empty = Seq.empty + inherit Monoid>() with + override self.Empty = Seq.empty override self.Append xs ys = Seq.append xs ys type EndoMonoid<'T>() = inherit Monoid<'T -> 'T>() with override self.Empty = id - override self.Append f g = f >> g \ No newline at end of file + override self.Append f g = f >> g diff --git a/src/Higher.Core/Option.fs b/src/Higher/Option.fs similarity index 54% rename from src/Higher.Core/Option.fs rename to src/Higher/Option.fs index 44b114a..db3dd71 100644 --- a/src/Higher.Core/Option.fs +++ b/src/Higher/Option.fs @@ -1,19 +1,18 @@ -namespace Higher.Core +namespace Higher -// Option Monad type +/// Option Monad type type Option private () = static let token = new Option() - static member Inj (value : 'T option) : App = + static member Inj (value : 'T option) : App = new App<_, _>(token, value) - static member Prj (app : App) : 'T option = + static member Prj (app : App) : 'T option = app.Apply(token) :?> _ -// Option Monad instance -type OptionMonad() = +/// Option Monad instance +type OptionMonad() = inherit Monad