somewhat initial
This commit is contained in:
commit
e18d12b0b3
23 changed files with 3885 additions and 0 deletions
2
.envrc
Normal file
2
.envrc
Normal file
|
@ -0,0 +1,2 @@
|
|||
watch_file *.cabal nix/modules/flake-parts/*.nix
|
||||
use flake
|
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
flake.lock linguist-generated=true
|
7
.github/CODE_OF_CONDUCT.md
vendored
Normal file
7
.github/CODE_OF_CONDUCT.md
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
This document, adapted from [The Ruby Community Conduct Guideline](https://www.ruby-lang.org/en/conduct/), provides community guidelines for a safe, respectful, productive, and collaborative place for any person who is willing to contribute to the associated project. It applies to all “collaborative space”, which is defined as community communications channels (such as mailing lists, submitted patches, commit comments, etc.).
|
||||
|
||||
- Participants will be tolerant of opposing views.
|
||||
- Participants must ensure that their language and actions are free of personal attacks and disparaging personal remarks.
|
||||
- When interpreting the words and actions of others, participants should always assume good intentions.
|
||||
- Behaviour which can be reasonably considered harassment will not be tolerated.
|
||||
|
22
.github/workflows/ci.yaml
vendored
Normal file
22
.github/workflows/ci.yaml
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
name: "CI"
|
||||
on:
|
||||
# Run only when pushing to master branch, and making PRs
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: DeterminateSystems/nix-installer-action@main
|
||||
- name: Install omnix
|
||||
run: nix --accept-flake-config profile install "github:juspay/omnix"
|
||||
- name: Build all flake outputs
|
||||
run: om ci
|
||||
- name: What GHC version?
|
||||
run: nix develop -c ghc --version
|
21
.github/workflows/update-flake-lock.yaml
vendored
Normal file
21
.github/workflows/update-flake-lock.yaml
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
name: update-flake-lock
|
||||
on:
|
||||
workflow_dispatch: # allows manual triggering
|
||||
# schedule:
|
||||
# - cron: '0 0 * * 0' # runs weekly on Sunday at 00:00
|
||||
|
||||
jobs:
|
||||
lockfile:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
- name: Install Nix
|
||||
uses: DeterminateSystems/nix-installer-action@main
|
||||
- name: Update flake.lock
|
||||
uses: DeterminateSystems/update-flake-lock@main
|
||||
with:
|
||||
token: ${{ secrets.GH_TOKEN_FOR_UPDATES }}
|
||||
pr-title: "Update flake.lock" # Title of PR to be created
|
||||
pr-labels: | # Labels to be set on the PR
|
||||
automated
|
12
.gitignore
vendored
Normal file
12
.gitignore
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
# cabal
|
||||
dist
|
||||
dist-*
|
||||
cabal.project.local
|
||||
cabal.project.local~
|
||||
|
||||
# nix
|
||||
result
|
||||
result-*
|
||||
|
||||
# direnv
|
||||
.direnv
|
3293
.hlint.yaml
Normal file
3293
.hlint.yaml
Normal file
File diff suppressed because it is too large
Load diff
10
.vscode/extensions.json
vendored
Normal file
10
.vscode/extensions.json
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"haskell.haskell",
|
||||
"bbenoist.nix",
|
||||
"jnoortheen.nix-ide",
|
||||
"mkhl.direnv"
|
||||
]
|
||||
}
|
11
.vscode/settings.json
vendored
Normal file
11
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"search.useIgnoreFiles": true,
|
||||
"editor.formatOnType": true,
|
||||
"editor.formatOnSave": true,
|
||||
"nixEnvSelector.nixFile": "${workspaceRoot}/shell.nix",
|
||||
// "nixEnvSelector.args": "--pure"
|
||||
"haskell.formattingProvider": "fourmolu",
|
||||
"haskell.manageHLS": "PATH",
|
||||
"nix.enableLanguageServer": true,
|
||||
"nix.serverPath": "nixd"
|
||||
}
|
21
LICENSE
Normal file
21
LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2022 Leon Vatthauer
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
42
README.md
Normal file
42
README.md
Normal file
|
@ -0,0 +1,42 @@
|
|||
# inductive-lambda
|
||||
|
||||
Get a Haskell development environment up and running quickly. Thanks to Nix, this template is optimized for a fully reproducible and friendly development environment. It is based on:
|
||||
|
||||
- [Nix](https://srid.ca/haskell-nix) + [Flakes](https://serokell.io/blog/practical-nix-flakes) (via [`github:srid/haskell-flake`](https://github.com/srid/haskell-flake)) + GHC 9.6
|
||||
- VSCode + [HLS](https://github.com/haskell/haskell-language-server)
|
||||
- [fourmolu](https://github.com/fourmolu/fourmolu) autoformatting
|
||||
- [Relude](https://github.com/kowainik/relude) as Prelude.
|
||||
- `.hlint.yaml` is [from relude](https://github.com/kowainik/relude/blob/main/.hlint.yaml)
|
||||
- Devshell commands are provided via [just](https://just.systems/); run `just` in devshell.
|
||||
|
||||
If you have an *existing* Haskell project, you should probably use https://github.com/srid/haskell-flake instead.
|
||||
|
||||
## Getting Started
|
||||
|
||||
Initialize this template using:
|
||||
|
||||
```sh
|
||||
nix --accept-flake-config run github:juspay/omnix -- \
|
||||
init github:srid/inductive-lambda -o ./yourproject
|
||||
```
|
||||
|
||||
*tldr: [Install Nix](https://nixos.asia/en/install), [setup direnv](https://nixos.asia/en/direnv), open in VSCode, install recommended extensions and run `just run`.*
|
||||
|
||||
Full instructions: https://srid.ca/inductive-lambda/start
|
||||
|
||||
Recommended dev environment setup: https://nixos.asia/en/direnv
|
||||
|
||||
## Tips
|
||||
|
||||
- Run `nix flake update` to update all flake inputs.
|
||||
- Run `nix --accept-flake-config run github:juspay/omnix ci` to build _all_ outputs.
|
||||
- Run `just fmt` in nix shell to autoformat the project. This uses [treefmt](https://github.com/numtide/treefmt).
|
||||
- Run `just docs` to start Hoogle with packages in your cabal file.
|
||||
- Run the application without installing: `nix run github:srid/inductive-lambda` (or `nix run .` from checkout)
|
||||
- Common workflows
|
||||
- Adding library dependencies in Nix: https://community.flake.parts/haskell-flake/dependency
|
||||
- Adding tests: https://srid.ca/inductive-lambda/tests
|
||||
|
||||
## Discussions
|
||||
|
||||
Questions? Ideas? Suggestions? Join our [NixOS Zulip](https://nixos.zulipchat.com/#narrow/stream/413949-haskell-flake) or post in [Github Discussions](https://github.com/srid/inductive-lambda/discussions).
|
117
flake.lock
generated
Normal file
117
flake.lock
generated
Normal file
|
@ -0,0 +1,117 @@
|
|||
{
|
||||
"nodes": {
|
||||
"flake-parts": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1730504689,
|
||||
"narHash": "sha256-hgmguH29K2fvs9szpq2r3pz2/8cJd2LPS+b4tfNFCwE=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "506278e768c2a08bec68eb62932193e341f55c90",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"fourmolu-nix": {
|
||||
"locked": {
|
||||
"lastModified": 1707266073,
|
||||
"narHash": "sha256-tCFzZQJicDdYjnuJiNK4hiiRAH7c2wQzMhOCdUMbVKE=",
|
||||
"owner": "jedimahdi",
|
||||
"repo": "fourmolu-nix",
|
||||
"rev": "717f5a91b0d7b97b1be7ecc3a0fd42d37ffe1c9b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "jedimahdi",
|
||||
"repo": "fourmolu-nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"haskell-flake": {
|
||||
"locked": {
|
||||
"lastModified": 1731272671,
|
||||
"narHash": "sha256-QS+dOZzsqLJ8NjhLCHp3zKD+d9nUThL/pcA4U0TlYBs=",
|
||||
"owner": "srid",
|
||||
"repo": "haskell-flake",
|
||||
"rev": "f42037d5e1a4ab012fc6783e2857e8dad511518c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "srid",
|
||||
"repo": "haskell-flake",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixos-unified": {
|
||||
"locked": {
|
||||
"lastModified": 1729697921,
|
||||
"narHash": "sha256-gqcmWE+4Vr5/l6AoQc2jIbJHCAXAY+qWPC0ruoAHV1Q=",
|
||||
"owner": "srid",
|
||||
"repo": "nixos-unified",
|
||||
"rev": "e60e64841e74c777799624531dcb2f311f95f639",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "srid",
|
||||
"repo": "nixos-unified",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1731531548,
|
||||
"narHash": "sha256-sz8/v17enkYmfpgeeuyzniGJU0QQBfmAjlemAUYhfy8=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "24f0d4acd634792badd6470134c387a3b039dace",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-parts": "flake-parts",
|
||||
"fourmolu-nix": "fourmolu-nix",
|
||||
"haskell-flake": "haskell-flake",
|
||||
"nixos-unified": "nixos-unified",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"treefmt-nix": "treefmt-nix"
|
||||
}
|
||||
},
|
||||
"treefmt-nix": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1730321837,
|
||||
"narHash": "sha256-vK+a09qq19QNu2MlLcvN4qcRctJbqWkX7ahgPZ/+maI=",
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"rev": "746901bb8dba96d154b66492a29f5db0693dbfcc",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
18
flake.nix
Normal file
18
flake.nix
Normal file
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
description = "Nix template for Haskell projects";
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
|
||||
flake-parts.url = "github:hercules-ci/flake-parts";
|
||||
flake-parts.inputs.nixpkgs-lib.follows = "nixpkgs";
|
||||
nixos-unified.url = "github:srid/nixos-unified";
|
||||
haskell-flake.url = "github:srid/haskell-flake";
|
||||
treefmt-nix.url = "github:numtide/treefmt-nix";
|
||||
treefmt-nix.inputs.nixpkgs.follows = "nixpkgs";
|
||||
fourmolu-nix.url = "github:jedimahdi/fourmolu-nix";
|
||||
};
|
||||
|
||||
outputs = inputs:
|
||||
# https://nixos-unified.org/autowiring.html#flake-parts
|
||||
inputs.nixos-unified.lib.mkFlake
|
||||
{ inherit inputs; root = ./.; };
|
||||
}
|
2
hie.yaml
Normal file
2
hie.yaml
Normal file
|
@ -0,0 +1,2 @@
|
|||
cradle:
|
||||
cabal:
|
102
inductive-lambda.cabal
Normal file
102
inductive-lambda.cabal
Normal file
|
@ -0,0 +1,102 @@
|
|||
cabal-version: 2.4
|
||||
name: inductive-lambda
|
||||
version: 0.1.0.0
|
||||
license: MIT
|
||||
copyright: 2022 Leon Vatthauer
|
||||
maintainer: srid@srid.ca
|
||||
author: Leon Vatthauer
|
||||
category: Web
|
||||
homepage: https://srid.ca/inductive-lambda
|
||||
|
||||
-- TODO: Before hackage release.
|
||||
-- A short (one-line) description of the package.
|
||||
synopsis: A template for Haskell projects using Nix
|
||||
|
||||
-- A longer description of the package.
|
||||
-- description:
|
||||
|
||||
-- A URL where users can report bugs.
|
||||
-- bug-reports:
|
||||
|
||||
extra-source-files:
|
||||
LICENSE
|
||||
README.md
|
||||
|
||||
common shared
|
||||
ghc-options:
|
||||
-Wall -Wincomplete-record-updates -Wincomplete-uni-patterns
|
||||
-Wmissing-deriving-strategies -Wunused-foralls -Wunused-foralls
|
||||
-fprint-explicit-foralls -fprint-explicit-kinds
|
||||
|
||||
mixins:
|
||||
base hiding (Prelude),
|
||||
relude (Relude as Prelude, Relude.Container.One),
|
||||
relude
|
||||
|
||||
default-extensions:
|
||||
BangPatterns
|
||||
ConstraintKinds
|
||||
DataKinds
|
||||
DeriveDataTypeable
|
||||
DeriveFoldable
|
||||
DeriveFunctor
|
||||
DeriveGeneric
|
||||
DeriveLift
|
||||
DeriveTraversable
|
||||
DerivingStrategies
|
||||
DerivingVia
|
||||
EmptyCase
|
||||
EmptyDataDecls
|
||||
EmptyDataDeriving
|
||||
ExistentialQuantification
|
||||
ExplicitForAll
|
||||
FlexibleContexts
|
||||
FlexibleInstances
|
||||
GADTSyntax
|
||||
GeneralisedNewtypeDeriving
|
||||
ImportQualifiedPost
|
||||
KindSignatures
|
||||
LambdaCase
|
||||
MultiParamTypeClasses
|
||||
MultiWayIf
|
||||
NoStarIsType
|
||||
NumericUnderscores
|
||||
OverloadedStrings
|
||||
PolyKinds
|
||||
PostfixOperators
|
||||
RankNTypes
|
||||
ScopedTypeVariables
|
||||
StandaloneDeriving
|
||||
StandaloneKindSignatures
|
||||
TupleSections
|
||||
TypeApplications
|
||||
TypeFamilies
|
||||
TypeOperators
|
||||
ViewPatterns
|
||||
|
||||
build-depends:
|
||||
, aeson
|
||||
, async
|
||||
, base >=4 && <5
|
||||
, data-default
|
||||
, directory
|
||||
, filepath
|
||||
, mtl
|
||||
, optics-core
|
||||
, profunctors
|
||||
, relude >=1.0
|
||||
, shower
|
||||
, time
|
||||
, with-utf8
|
||||
, megaparsec
|
||||
|
||||
hs-source-dirs: src
|
||||
default-language: Haskell2010
|
||||
|
||||
executable inductive-lambda
|
||||
import: shared
|
||||
main-is: Main.hs
|
||||
other-modules:
|
||||
Syntax.Parser
|
||||
Syntax.Lexer
|
||||
Syntax.AST
|
19
justfile
Normal file
19
justfile
Normal file
|
@ -0,0 +1,19 @@
|
|||
default:
|
||||
@just --list
|
||||
|
||||
# Run hoogle
|
||||
docs:
|
||||
echo http://127.0.0.1:8888
|
||||
hoogle serve -p 8888 --local
|
||||
|
||||
# Run cabal repl
|
||||
repl *ARGS:
|
||||
cabal repl {{ARGS}}
|
||||
|
||||
# Autoformat the project tree
|
||||
fmt:
|
||||
treefmt
|
||||
|
||||
# Run ghcid -- auto-recompile and run `main` function
|
||||
run:
|
||||
ghcid -T :main
|
19
nix/modules/flake-parts/devshell.nix
Normal file
19
nix/modules/flake-parts/devshell.nix
Normal file
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
perSystem = { config, pkgs, ... }: {
|
||||
# Default shell.
|
||||
devShells.default = pkgs.mkShell {
|
||||
name = "inductive-lambda";
|
||||
meta.description = "Haskell development environment";
|
||||
# See https://community.flake.parts/haskell-flake/devshell#composing-devshells
|
||||
inputsFrom = [
|
||||
config.haskellProjects.default.outputs.devShell # See ./nix/modules/haskell.nix
|
||||
config.treefmt.build.devShell # See ./nix/modules/formatter.nix
|
||||
];
|
||||
packages = with pkgs; [
|
||||
just
|
||||
nixd
|
||||
ghciwatch
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
34
nix/modules/flake-parts/formatter.nix
Normal file
34
nix/modules/flake-parts/formatter.nix
Normal file
|
@ -0,0 +1,34 @@
|
|||
{ inputs, ... }:
|
||||
{
|
||||
imports = [
|
||||
inputs.treefmt-nix.flakeModule
|
||||
inputs.fourmolu-nix.flakeModule
|
||||
];
|
||||
perSystem = { config, pkgs, ... }: {
|
||||
# Auto formatters. This also adds a flake check to ensure that the
|
||||
# source tree was auto formatted.
|
||||
treefmt.config = {
|
||||
projectRootFile = "flake.nix";
|
||||
|
||||
programs.fourmolu = {
|
||||
enable = true;
|
||||
package = config.fourmolu.wrapper;
|
||||
};
|
||||
programs.nixpkgs-fmt.enable = true;
|
||||
programs.cabal-fmt.enable = true;
|
||||
programs.hlint.enable = true;
|
||||
};
|
||||
|
||||
fourmolu.settings = {
|
||||
indentation = 2;
|
||||
comma-style = "leading";
|
||||
record-brace-space = true;
|
||||
indent-wheres = true;
|
||||
import-export-style = "diff-friendly";
|
||||
respectful = true;
|
||||
haddock-style = "multi-line";
|
||||
newlines-between-decls = 1;
|
||||
extensions = [ "ImportQualifiedPost" ];
|
||||
};
|
||||
};
|
||||
}
|
61
nix/modules/flake-parts/haskell.nix
Normal file
61
nix/modules/flake-parts/haskell.nix
Normal file
|
@ -0,0 +1,61 @@
|
|||
{ root, inputs, ... }:
|
||||
{
|
||||
imports = [
|
||||
inputs.haskell-flake.flakeModule
|
||||
];
|
||||
perSystem = { self', lib, config, pkgs, ... }: {
|
||||
# Our only Haskell project. You can have multiple projects, but this template
|
||||
# has only one.
|
||||
# See https://github.com/srid/haskell-flake/blob/master/example/flake.nix
|
||||
haskellProjects.default = {
|
||||
# To avoid unnecessary rebuilds, we filter projectRoot:
|
||||
# https://community.flake.parts/haskell-flake/local#rebuild
|
||||
projectRoot = builtins.toString (lib.fileset.toSource {
|
||||
inherit root;
|
||||
fileset = lib.fileset.unions [
|
||||
(root + /src)
|
||||
(root + /inductive-lambda.cabal)
|
||||
(root + /LICENSE)
|
||||
(root + /README.md)
|
||||
];
|
||||
});
|
||||
|
||||
# The base package set (this value is the default)
|
||||
# basePackages = pkgs.haskellPackages;
|
||||
|
||||
# Packages to add on top of `basePackages`
|
||||
packages = {
|
||||
# Add source or Hackage overrides here
|
||||
# (Local packages are added automatically)
|
||||
/*
|
||||
aeson.source = "1.5.0.0" # Hackage version
|
||||
shower.source = inputs.shower; # Flake input
|
||||
*/
|
||||
};
|
||||
|
||||
# Add your package overrides here
|
||||
settings = {
|
||||
/*
|
||||
inductive-lambda = {
|
||||
haddock = false;
|
||||
};
|
||||
aeson = {
|
||||
check = false;
|
||||
};
|
||||
*/
|
||||
};
|
||||
|
||||
# Development shell configuration
|
||||
devShell = {
|
||||
hlsCheck.enable = false;
|
||||
};
|
||||
|
||||
# What should haskell-flake add to flake outputs?
|
||||
autoWire = [ "packages" "apps" "checks" ]; # Wire all but the devShell
|
||||
};
|
||||
|
||||
# Default package & app.
|
||||
packages.default = self'.packages.inductive-lambda;
|
||||
apps.default = self'.apps.inductive-lambda;
|
||||
};
|
||||
}
|
16
src/Main.hs
Normal file
16
src/Main.hs
Normal file
|
@ -0,0 +1,16 @@
|
|||
module Main where
|
||||
|
||||
import Main.Utf8 qualified as Utf8
|
||||
import Syntax.Parser
|
||||
|
||||
{- |
|
||||
Main entry point.
|
||||
|
||||
`just run` will invoke this function.
|
||||
-}
|
||||
main :: IO ()
|
||||
main = do
|
||||
-- For withUtf8, see https://serokell.io/blog/haskell-with-utf8
|
||||
Utf8.withUtf8 $ do
|
||||
putTextLn "Hello 🌎 (from inductive-lambda)"
|
||||
parser_main
|
12
src/Syntax/AST.hs
Normal file
12
src/Syntax/AST.hs
Normal file
|
@ -0,0 +1,12 @@
|
|||
module Syntax.AST where
|
||||
|
||||
import Data.Text (Text)
|
||||
import Prelude hiding (Type)
|
||||
|
||||
type Name = Text
|
||||
|
||||
data Term = Variable Name | Application Name [Term]
|
||||
data Declaration = Declaration Name [Type]
|
||||
data Definition = Definition Name Term
|
||||
data Data = Data Name [Declaration]
|
||||
data Type = Atomic Name | Arrow Type Type
|
1
src/Syntax/Lexer.hs
Normal file
1
src/Syntax/Lexer.hs
Normal file
|
@ -0,0 +1 @@
|
|||
module Syntax.Lexer where
|
42
src/Syntax/Parser.hs
Normal file
42
src/Syntax/Parser.hs
Normal file
|
@ -0,0 +1,42 @@
|
|||
{-# LANGUAGE OverloadedStrings #-}
|
||||
|
||||
module Syntax.Parser where
|
||||
|
||||
import Data.Text (Text, unpack)
|
||||
import Data.Void (Void)
|
||||
import Text.Megaparsec
|
||||
import Text.Megaparsec.Char (space)
|
||||
|
||||
import Syntax.AST
|
||||
|
||||
type Parser = Parsec Void Text
|
||||
|
||||
-- helper function to run parser
|
||||
parseAndPrint :: (Show b) => Parsec Void Text b -> Text -> IO ()
|
||||
parseAndPrint parser line =
|
||||
either
|
||||
(putStrLn . errorBundlePretty)
|
||||
print
|
||||
(runParser parser "" line)
|
||||
|
||||
-- parse 'a' then 'b'
|
||||
abParser :: Parser Text
|
||||
abParser = "ab" -- (2)!
|
||||
|
||||
-- parse 'b' then 'a'
|
||||
baParser :: Parser Text
|
||||
baParser = "ba"
|
||||
|
||||
-- parse 'ab' then 'ba'
|
||||
abbaParser :: Parser Text -- (1)!
|
||||
abbaParser = do
|
||||
ab <- abParser -- (3)!
|
||||
ba <- baParser -- (4)!
|
||||
return (ab <> ba) -- (5)!
|
||||
|
||||
-- parse either 'ba' or 'ab'
|
||||
baOrabParser :: Parser Text
|
||||
baOrabParser = baParser <|> abParser -- (6)!
|
||||
|
||||
parser_main :: IO ()
|
||||
parser_main = parseAndPrint abbaParser "abbaasd"
|
Loading…
Reference in a new issue