mirror of
https://github.com/tfausak/witch.git
synced 2024-11-22 14:58:13 +03:00
Update things for 2023 (#81)
This commit is contained in:
parent
cb6d96e949
commit
6e1a255e31
6
.devcontainer.json
Normal file
6
.devcontainer.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"dockerComposeFile": "compose.yaml",
|
||||||
|
"initializeCommand": "docker volume create cabal-store",
|
||||||
|
"service": "devcontainer",
|
||||||
|
"workspaceFolder": "/workspaces/witch"
|
||||||
|
}
|
@ -1,9 +0,0 @@
|
|||||||
#! /usr/bin/env sh
|
|
||||||
set -o errexit -o xtrace
|
|
||||||
|
|
||||||
if ! command -v "$1" >&2
|
|
||||||
then
|
|
||||||
cabal install "$1" >&2
|
|
||||||
fi
|
|
||||||
|
|
||||||
exec "$@"
|
|
@ -1,14 +0,0 @@
|
|||||||
services:
|
|
||||||
devcontainer:
|
|
||||||
command: sh -c 'while sleep 1; do :; done'
|
|
||||||
image: public.ecr.aws/acilearning/haskell:9.2.5-7bd251ac55c29968002b10e3d012562e86d3f218
|
|
||||||
init: true
|
|
||||||
volumes:
|
|
||||||
- ..:/workspaces/witch
|
|
||||||
- cabal:/home/haskell/.cabal
|
|
||||||
- cabal-store:/cabal-store
|
|
||||||
working_dir: /workspaces/witch
|
|
||||||
volumes:
|
|
||||||
cabal: null
|
|
||||||
cabal-store:
|
|
||||||
external: true
|
|
@ -1,16 +0,0 @@
|
|||||||
{
|
|
||||||
"dockerComposeFile": "compose.yaml",
|
|
||||||
"extensions": [
|
|
||||||
"taylorfausak.purple-yolk"
|
|
||||||
],
|
|
||||||
"initializeCommand": ".devcontainer/initialize.sh",
|
|
||||||
"onCreateCommand": ".devcontainer/on-create.sh",
|
|
||||||
"service": "devcontainer",
|
|
||||||
"settings": {
|
|
||||||
"editor.formatOnSave": true,
|
|
||||||
"purple-yolk.haskell.formatter.command": ".devcontainer/cabal-shim.sh ormolu --no-cabal",
|
|
||||||
"purple-yolk.haskell.linter.command": ".devcontainer/cabal-shim.sh hlint --json --no-exit-code -",
|
|
||||||
"purple-yolk.haskell.linter.onSave": true
|
|
||||||
},
|
|
||||||
"workspaceFolder": "/workspaces/witch"
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
#! /usr/bin/env sh
|
|
||||||
set -o errexit -o xtrace
|
|
||||||
|
|
||||||
volume=cabal-store
|
|
||||||
if ! docker volume inspect "$volume"
|
|
||||||
then
|
|
||||||
docker volume create "$volume"
|
|
||||||
fi
|
|
@ -1,9 +0,0 @@
|
|||||||
#! /usr/bin/env sh
|
|
||||||
set -o errexit -o xtrace
|
|
||||||
|
|
||||||
cabal update
|
|
||||||
|
|
||||||
if ! test -f cabal.project.local
|
|
||||||
then
|
|
||||||
cabal configure --enable-tests --jobs --test-show-details direct
|
|
||||||
fi
|
|
18
.github/dependabot.yaml
vendored
18
.github/dependabot.yaml
vendored
@ -1,6 +1,12 @@
|
|||||||
version: 2
|
{
|
||||||
updates:
|
"updates": [
|
||||||
- package-ecosystem: github-actions
|
{
|
||||||
directory: /
|
"directory": "/",
|
||||||
schedule:
|
"package-ecosystem": "github-actions",
|
||||||
interval: daily
|
"schedule": {
|
||||||
|
"interval": "daily"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": 2
|
||||||
|
}
|
||||||
|
324
.github/workflows/workflow.yaml
vendored
324
.github/workflows/workflow.yaml
vendored
@ -1,131 +1,193 @@
|
|||||||
name: Workflow
|
{
|
||||||
on:
|
"jobs": {
|
||||||
push: null
|
"build": {
|
||||||
release:
|
"name": "Build on ${{ matrix.platform }} with GHC ${{ matrix.ghc }}",
|
||||||
types:
|
"runs-on": "${{ matrix.platform }}-${{ matrix.version }}",
|
||||||
- created
|
"steps": [
|
||||||
|
{
|
||||||
jobs:
|
"uses": "actions/checkout@v3"
|
||||||
cabal:
|
},
|
||||||
runs-on: ubuntu-latest
|
{
|
||||||
name: Cabal
|
"run": "mkdir artifact"
|
||||||
steps:
|
},
|
||||||
- uses: actions/checkout@v3
|
{
|
||||||
|
"id": "artifact",
|
||||||
- run: cabal check
|
"run": "echo 'directory=artifact/${{ matrix.platform }}-${{ matrix.ghc }}' >> $GITHUB_OUTPUT",
|
||||||
|
"shell": "bash"
|
||||||
hlint:
|
},
|
||||||
runs-on: ubuntu-latest
|
{
|
||||||
name: HLint
|
"run": "mkdir ${{ steps.artifact.outputs.directory }}"
|
||||||
steps:
|
},
|
||||||
- uses: actions/checkout@v3
|
{
|
||||||
|
"id": "haskell",
|
||||||
- uses: haskell/actions/hlint-setup@v2
|
"uses": "haskell/actions/setup@v2",
|
||||||
|
"with": {
|
||||||
- uses: haskell/actions/hlint-run@v2
|
"cabal-version": "3.8.1.0",
|
||||||
with:
|
"ghc-version": "${{ matrix.ghc }}"
|
||||||
fail-on: status
|
}
|
||||||
|
},
|
||||||
ormolu:
|
{
|
||||||
runs-on: ubuntu-latest
|
"run": "cabal sdist --output-dir ${{ steps.artifact.outputs.directory }}"
|
||||||
name: Ormolu
|
},
|
||||||
steps:
|
{
|
||||||
- uses: actions/checkout@v3
|
"run": "cabal configure --enable-optimization=2 --flags pedantic --jobs"
|
||||||
|
},
|
||||||
- uses: mrkkrp/ormolu-action@v9
|
{
|
||||||
|
"run": "cat cabal.project.local"
|
||||||
build:
|
},
|
||||||
strategy:
|
{
|
||||||
matrix:
|
"run": "cp cabal.project.local ${{ steps.artifact.outputs.directory }}"
|
||||||
include:
|
},
|
||||||
- { platform: ubuntu, ghc: 9.4.2 }
|
{
|
||||||
- { platform: ubuntu, ghc: 9.2.5 }
|
"run": "cabal freeze"
|
||||||
- { platform: ubuntu, ghc: 9.0.2 }
|
},
|
||||||
- { platform: macos, ghc: 9.4.2 }
|
{
|
||||||
- { platform: windows, ghc: 9.4.2 }
|
"run": "cat cabal.project.freeze"
|
||||||
- { platform: ubuntu, ghc: 8.10.7 }
|
},
|
||||||
- { platform: ubuntu, ghc: 8.8.4 }
|
{
|
||||||
- { platform: ubuntu, ghc: 8.6.5 }
|
"run": "cp cabal.project.freeze ${{ steps.artifact.outputs.directory }}"
|
||||||
- { platform: ubuntu, ghc: 8.4.4 }
|
},
|
||||||
- { platform: ubuntu, ghc: 8.2.2 }
|
{
|
||||||
runs-on: ${{ matrix.platform }}-latest
|
"run": "cabal outdated --v2-freeze-file cabal.project.freeze"
|
||||||
name: GHC ${{ matrix.ghc }} on ${{ matrix.platform }}
|
},
|
||||||
steps:
|
{
|
||||||
- uses: actions/checkout@v3
|
"uses": "actions/cache@v3",
|
||||||
|
"with": {
|
||||||
- run: mkdir artifact
|
"key": "${{ matrix.platform }}-${{ matrix.ghc }}-${{ hashFiles('cabal.project.freeze') }}",
|
||||||
|
"path": "${{ steps.haskell.outputs.cabal-store }}",
|
||||||
- id: artifact
|
"restore-keys": "${{ matrix.platform }}-${{ matrix.ghc }}-"
|
||||||
run: echo '::set-output name=directory::artifact/${{ matrix.platform }}-${{ matrix.ghc }}'
|
}
|
||||||
|
},
|
||||||
- run: mkdir ${{ steps.artifact.outputs.directory }}
|
{
|
||||||
|
"run": "cabal build --only-download"
|
||||||
# https://discourse.haskell.org/t/incident-github-actions-ci-failure-ghcup/5761
|
},
|
||||||
- if: matrix.platform == 'ubuntu'
|
{
|
||||||
run: sudo chown -R $USER /usr/local/.ghcup
|
"run": "cabal build --only-dependencies"
|
||||||
|
},
|
||||||
- id: setup-haskell
|
{
|
||||||
uses: haskell/actions/setup@v2
|
"run": "cabal build"
|
||||||
with:
|
},
|
||||||
ghc-version: ${{ matrix.ghc }}
|
{
|
||||||
|
"uses": "actions/upload-artifact@v3",
|
||||||
- run: cabal configure --enable-tests --flags pedantic --jobs
|
"with": {
|
||||||
|
"name": "witch-${{ github.sha }}",
|
||||||
- run: cat cabal.project.local
|
"path": "artifact"
|
||||||
|
}
|
||||||
- run: cp cabal.project.local ${{ steps.artifact.outputs.directory }}
|
},
|
||||||
|
{
|
||||||
- run: cabal freeze
|
"run": "cabal run witch-test-suite"
|
||||||
|
}
|
||||||
- run: cat cabal.project.freeze
|
],
|
||||||
|
"strategy": {
|
||||||
- run: cp cabal.project.freeze ${{ steps.artifact.outputs.directory }}
|
"matrix": {
|
||||||
|
"include": [
|
||||||
- uses: actions/cache@v3
|
{
|
||||||
with:
|
"ghc": "9.4.4",
|
||||||
path: ${{ steps.setup-haskell.outputs.cabal-store }}
|
"platform": "macos",
|
||||||
key: ${{ matrix.platform }}-${{ matrix.ghc }}-${{ hashFiles('cabal.project.freeze') }}
|
"version": "12"
|
||||||
restore-keys: ${{ matrix.platform }}-${{ matrix.ghc }}-
|
},
|
||||||
|
{
|
||||||
- run: cabal build --only-download
|
"ghc": "9.0.2",
|
||||||
|
"platform": "ubuntu",
|
||||||
- run: cabal build --only-dependencies
|
"version": "22.04"
|
||||||
|
},
|
||||||
- run: cabal build
|
{
|
||||||
|
"ghc": "9.2.5",
|
||||||
- run: cabal run -- witch-test-suite
|
"platform": "ubuntu",
|
||||||
|
"version": "22.04"
|
||||||
- run: cabal sdist --output-dir ${{ steps.artifact.outputs.directory }}
|
},
|
||||||
|
{
|
||||||
- uses: actions/upload-artifact@v3
|
"ghc": "9.4.4",
|
||||||
with:
|
"platform": "ubuntu",
|
||||||
path: artifact
|
"version": "22.04"
|
||||||
name: witch-${{ github.sha }}
|
},
|
||||||
|
{
|
||||||
release:
|
"extension": ".exe",
|
||||||
needs: build
|
"ghc": "9.4.4",
|
||||||
if: github.event_name == 'release'
|
"platform": "windows",
|
||||||
runs-on: ubuntu-latest
|
"version": "2022"
|
||||||
steps:
|
}
|
||||||
- uses: actions/download-artifact@v3
|
]
|
||||||
with:
|
}
|
||||||
name: witch-${{ github.sha }}
|
}
|
||||||
path: artifact
|
},
|
||||||
|
"cabal": {
|
||||||
- uses: actions/upload-release-asset@v1
|
"name": "Cabal",
|
||||||
env:
|
"runs-on": "ubuntu-22.04",
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
"steps": [
|
||||||
with:
|
{
|
||||||
asset_content_type: application/gzip
|
"uses": "actions/checkout@v3"
|
||||||
asset_name: witch-${{ github.event.release.tag_name }}.tar.gz
|
},
|
||||||
asset_path: artifact/ubuntu-9.4.2/witch-${{ github.event.release.tag_name }}.tar.gz
|
{
|
||||||
upload_url: ${{ github.event.release.upload_url }}
|
"run": "cabal check"
|
||||||
|
}
|
||||||
- run: cabal upload --publish --username '${{ secrets.HACKAGE_USERNAME }}' --password '${{ secrets.HACKAGE_PASSWORD }}' artifact/ubuntu-9.4.2/witch-${{ github.event.release.tag_name }}.tar.gz
|
]
|
||||||
|
},
|
||||||
i386:
|
"hlint": {
|
||||||
runs-on: ubuntu-latest
|
"name": "HLint",
|
||||||
steps:
|
"runs-on": "ubuntu-22.04",
|
||||||
- uses: actions/checkout@v2
|
"steps": [
|
||||||
|
{
|
||||||
- run: docker run --rm --user 0 --volume "$PWD:$PWD" --workdir "$PWD" taylorfausak/i386-haskell@sha256:450720742fa69258c0a8589dcac28c3c6d5d34718172d935b385520f4ee9128e sh -c 'cabal update && cabal test --test-show-details direct'
|
"uses": "actions/checkout@v3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uses": "haskell/actions/hlint-setup@v2",
|
||||||
|
"with": {
|
||||||
|
"version": 3.5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ormolu": {
|
||||||
|
"name": "Ormolu",
|
||||||
|
"runs-on": "ubuntu-22.04",
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"uses": "actions/checkout@v3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uses": "mrkkrp/ormolu-action@v10"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"release": {
|
||||||
|
"if": "github.event_name == 'release'",
|
||||||
|
"name": "Release",
|
||||||
|
"needs": "build",
|
||||||
|
"runs-on": "ubuntu-22.04",
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"uses": "actions/download-artifact@v3",
|
||||||
|
"with": {
|
||||||
|
"name": "witch-${{ github.sha }}",
|
||||||
|
"path": "artifact"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uses": "svenstaro/upload-release-action@v2",
|
||||||
|
"with": {
|
||||||
|
"asset_name": "witch-${{ github.event.release.tag_name }}.tar.gz",
|
||||||
|
"file": "artifact/ubuntu-9.4.4/witch-${{ github.event.release.tag_name }}.tar.gz"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"run": "cabal upload --publish --username '${{ secrets.HACKAGE_USERNAME }}' --password '${{ secrets.HACKAGE_PASSWORD }}' artifact/ubuntu-9.4.4/witch-${{ github.event.release.tag_name }}.tar.gz"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "Workflow",
|
||||||
|
"on": {
|
||||||
|
"push": null,
|
||||||
|
"release": {
|
||||||
|
"types": [
|
||||||
|
"created"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"schedule": [
|
||||||
|
{
|
||||||
|
"cron": "0 0 * * *"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
32
.hlint.yaml
32
.hlint.yaml
@ -1,3 +1,29 @@
|
|||||||
- group: { name: dollar, enabled: true }
|
[
|
||||||
- ignore: { name: Use lambda-case }
|
{
|
||||||
- ignore: { name: Use tuple-section }
|
"group": {
|
||||||
|
"enabled": true,
|
||||||
|
"name": "dollar"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"group": {
|
||||||
|
"enabled": true,
|
||||||
|
"name": "generalise"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ignore": {
|
||||||
|
"name": "Use lambda-case"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ignore": {
|
||||||
|
"name": "Use tuple-section"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ignore": {
|
||||||
|
"name": "Redundant bracket"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2022 Taylor Fausak
|
Copyright (c) 2023 Taylor Fausak
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# Witch
|
# Witch
|
||||||
|
|
||||||
[![CI](https://github.com/tfausak/witch/workflows/Workflow/badge.svg)](https://github.com/tfausak/witch/actions)
|
[![Workflow](https://github.com/tfausak/witch/actions/workflows/workflow.yaml/badge.svg)](https://github.com/tfausak/witch/actions/workflows/workflow.yaml)
|
||||||
[![Hackage](https://img.shields.io/hackage/v/witch)](https://hackage.haskell.org/package/witch)
|
[![Hackage](https://img.shields.io/hackage/v/witch)](https://hackage.haskell.org/package/witch)
|
||||||
[![Stackage](https://www.stackage.org/package/witch/badge/nightly?label=stackage)](https://www.stackage.org/package/witch)
|
[![Stackage](https://www.stackage.org/package/witch/badge/nightly?label=stackage)](https://www.stackage.org/package/witch)
|
||||||
|
|
||||||
|
21
compose.yaml
Normal file
21
compose.yaml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"services": {
|
||||||
|
"devcontainer": {
|
||||||
|
"command": "sh -c 'while sleep 1; do :; done'",
|
||||||
|
"image": "public.ecr.aws/acilearning/haskell:9.4.4",
|
||||||
|
"init": true,
|
||||||
|
"volumes": [
|
||||||
|
".:/workspaces/witch",
|
||||||
|
"cabal:/home/haskell/.cabal",
|
||||||
|
"cabal-store:/cabal-store"
|
||||||
|
],
|
||||||
|
"working_dir": "/workspaces/witch"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"volumes": {
|
||||||
|
"cabal": null,
|
||||||
|
"cabal-store": {
|
||||||
|
"external": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,48 +0,0 @@
|
|||||||
{-# LANGUAGE ExplicitForAll #-}
|
|
||||||
|
|
||||||
module Witch.Lift where
|
|
||||||
|
|
||||||
import qualified Data.Typeable as Typeable
|
|
||||||
import qualified Language.Haskell.TH.Syntax as TH
|
|
||||||
import qualified Witch.TryFrom as TryFrom
|
|
||||||
import qualified Witch.Utility as Utility
|
|
||||||
|
|
||||||
-- | This is like 'Utility.unsafeFrom' except that it works at compile time
|
|
||||||
-- rather than runtime.
|
|
||||||
--
|
|
||||||
-- > -- Avoid this:
|
|
||||||
-- > unsafeFrom @s "some literal"
|
|
||||||
-- >
|
|
||||||
-- > -- Prefer this:
|
|
||||||
-- > $$(liftedFrom @s "some literal")
|
|
||||||
liftedFrom ::
|
|
||||||
forall source target.
|
|
||||||
( TryFrom.TryFrom source target,
|
|
||||||
TH.Lift target,
|
|
||||||
Show source,
|
|
||||||
Typeable.Typeable source,
|
|
||||||
Typeable.Typeable target
|
|
||||||
) =>
|
|
||||||
source ->
|
|
||||||
TH.Q (TH.TExp target)
|
|
||||||
liftedFrom = TH.liftTyped . Utility.unsafeFrom
|
|
||||||
|
|
||||||
-- | This is like 'Utility.unsafeInto' except that it works at compile time
|
|
||||||
-- rather than runtime.
|
|
||||||
--
|
|
||||||
-- > -- Avoid this:
|
|
||||||
-- > unsafeInto @t "some literal"
|
|
||||||
-- >
|
|
||||||
-- > -- Prefer this:
|
|
||||||
-- > $$(liftedInto @t "some literal")
|
|
||||||
liftedInto ::
|
|
||||||
forall target source.
|
|
||||||
( TryFrom.TryFrom source target,
|
|
||||||
TH.Lift target,
|
|
||||||
Show source,
|
|
||||||
Typeable.Typeable source,
|
|
||||||
Typeable.Typeable target
|
|
||||||
) =>
|
|
||||||
source ->
|
|
||||||
TH.Q (TH.TExp target)
|
|
||||||
liftedInto = liftedFrom
|
|
@ -1,48 +0,0 @@
|
|||||||
{-# LANGUAGE ScopedTypeVariables #-}
|
|
||||||
|
|
||||||
module Witch.Lift where
|
|
||||||
|
|
||||||
import qualified Data.Typeable as Typeable
|
|
||||||
import qualified Language.Haskell.TH.Syntax as TH
|
|
||||||
import qualified Witch.TryFrom as TryFrom
|
|
||||||
import qualified Witch.Utility as Utility
|
|
||||||
|
|
||||||
-- | This is like 'Utility.unsafeFrom' except that it works at compile time
|
|
||||||
-- rather than runtime.
|
|
||||||
--
|
|
||||||
-- > -- Avoid this:
|
|
||||||
-- > unsafeFrom @s "some literal"
|
|
||||||
-- >
|
|
||||||
-- > -- Prefer this:
|
|
||||||
-- > $$(liftedFrom @s "some literal")
|
|
||||||
liftedFrom ::
|
|
||||||
forall source target.
|
|
||||||
( TryFrom.TryFrom source target,
|
|
||||||
TH.Lift target,
|
|
||||||
Show source,
|
|
||||||
Typeable.Typeable source,
|
|
||||||
Typeable.Typeable target
|
|
||||||
) =>
|
|
||||||
source ->
|
|
||||||
TH.Q (TH.TExp target)
|
|
||||||
liftedFrom s = TH.unsafeTExpCoerce $ TH.lift (Utility.unsafeFrom s :: target)
|
|
||||||
|
|
||||||
-- | This is like 'Utility.unsafeInto' except that it works at compile time
|
|
||||||
-- rather than runtime.
|
|
||||||
--
|
|
||||||
-- > -- Avoid this:
|
|
||||||
-- > unsafeInto @t "some literal"
|
|
||||||
-- >
|
|
||||||
-- > -- Prefer this:
|
|
||||||
-- > $$(liftedInto @t "some literal")
|
|
||||||
liftedInto ::
|
|
||||||
forall target source.
|
|
||||||
( TryFrom.TryFrom source target,
|
|
||||||
TH.Lift target,
|
|
||||||
Show source,
|
|
||||||
Typeable.Typeable source,
|
|
||||||
Typeable.Typeable target
|
|
||||||
) =>
|
|
||||||
source ->
|
|
||||||
TH.Q (TH.TExp target)
|
|
||||||
liftedInto = liftedFrom
|
|
@ -31,5 +31,5 @@ class From source target where
|
|||||||
-- >>> instance From Name String
|
-- >>> instance From Name String
|
||||||
-- >>> instance From String Name
|
-- >>> instance From String Name
|
||||||
from :: source -> target
|
from :: source -> target
|
||||||
default from :: Coerce.Coercible source target => source -> target
|
default from :: (Coerce.Coercible source target) => source -> target
|
||||||
from = Coerce.coerce
|
from = Coerce.coerce
|
||||||
|
@ -911,7 +911,7 @@ instance From.From Double Float where
|
|||||||
-- Ratio
|
-- Ratio
|
||||||
|
|
||||||
-- | Uses '(Ratio.%)' with a denominator of 1.
|
-- | Uses '(Ratio.%)' with a denominator of 1.
|
||||||
instance Integral a => From.From a (Ratio.Ratio a) where
|
instance (Integral a) => From.From a (Ratio.Ratio a) where
|
||||||
from = (Ratio.% 1)
|
from = (Ratio.% 1)
|
||||||
|
|
||||||
-- | Uses 'Ratio.numerator' when the denominator is 1.
|
-- | Uses 'Ratio.numerator' when the denominator is 1.
|
||||||
@ -930,7 +930,7 @@ instance From.From Rational Double where
|
|||||||
from = fromRational
|
from = fromRational
|
||||||
|
|
||||||
-- | Uses `fromRational` as long as there isn't a loss of precision.
|
-- | Uses `fromRational` as long as there isn't a loss of precision.
|
||||||
instance Fixed.HasResolution a => TryFrom.TryFrom Rational (Fixed.Fixed a) where
|
instance (Fixed.HasResolution a) => TryFrom.TryFrom Rational (Fixed.Fixed a) where
|
||||||
tryFrom = Utility.eitherTryFrom $ \s ->
|
tryFrom = Utility.eitherTryFrom $ \s ->
|
||||||
let t :: Fixed.Fixed a
|
let t :: Fixed.Fixed a
|
||||||
t = fromRational s
|
t = fromRational s
|
||||||
@ -949,13 +949,13 @@ instance From.From (Fixed.Fixed a) Integer where
|
|||||||
from (Fixed.MkFixed t) = t
|
from (Fixed.MkFixed t) = t
|
||||||
|
|
||||||
-- | Uses 'toRational'.
|
-- | Uses 'toRational'.
|
||||||
instance Fixed.HasResolution a => From.From (Fixed.Fixed a) Rational where
|
instance (Fixed.HasResolution a) => From.From (Fixed.Fixed a) Rational where
|
||||||
from = toRational
|
from = toRational
|
||||||
|
|
||||||
-- Complex
|
-- Complex
|
||||||
|
|
||||||
-- | Uses '(Complex.:+)' with an imaginary part of 0.
|
-- | Uses '(Complex.:+)' with an imaginary part of 0.
|
||||||
instance Num a => From.From a (Complex.Complex a) where
|
instance (Num a) => From.From a (Complex.Complex a) where
|
||||||
from = (Complex.:+ 0)
|
from = (Complex.:+ 0)
|
||||||
|
|
||||||
-- | Uses 'Complex.realPart' when the imaginary part is 0.
|
-- | Uses 'Complex.realPart' when the imaginary part is 0.
|
||||||
@ -978,7 +978,7 @@ instance From.From (NonEmpty.NonEmpty a) [a] where
|
|||||||
-- Set
|
-- Set
|
||||||
|
|
||||||
-- | Uses 'Set.fromList'.
|
-- | Uses 'Set.fromList'.
|
||||||
instance Ord a => From.From [a] (Set.Set a) where
|
instance (Ord a) => From.From [a] (Set.Set a) where
|
||||||
from = Set.fromList
|
from = Set.fromList
|
||||||
|
|
||||||
-- | Uses 'Set.toAscList'.
|
-- | Uses 'Set.toAscList'.
|
||||||
@ -999,7 +999,7 @@ instance From.From IntSet.IntSet [Int] where
|
|||||||
|
|
||||||
-- | Uses 'Map.fromList'. If there are duplicate keys, later values will
|
-- | Uses 'Map.fromList'. If there are duplicate keys, later values will
|
||||||
-- overwrite earlier ones.
|
-- overwrite earlier ones.
|
||||||
instance Ord k => From.From [(k, v)] (Map.Map k v) where
|
instance (Ord k) => From.From [(k, v)] (Map.Map k v) where
|
||||||
from = Map.fromList
|
from = Map.fromList
|
||||||
|
|
||||||
-- | Uses 'Map.toAscList'.
|
-- | Uses 'Map.toAscList'.
|
||||||
@ -1539,7 +1539,7 @@ instance From.From String (Encoding.UTF_32BE LazyByteString.ByteString) where
|
|||||||
--
|
--
|
||||||
|
|
||||||
realFloatToRational ::
|
realFloatToRational ::
|
||||||
RealFloat s => s -> Either Exception.ArithException Rational
|
(RealFloat s) => s -> Either Exception.ArithException Rational
|
||||||
realFloatToRational s
|
realFloatToRational s
|
||||||
| isNaN s = Left Exception.LossOfPrecision
|
| isNaN s = Left Exception.LossOfPrecision
|
||||||
| isInfinite s =
|
| isInfinite s =
|
||||||
@ -1569,13 +1569,13 @@ fromNonNegativeIntegral x =
|
|||||||
|
|
||||||
-- | The maximum integral value that can be unambiguously represented as a
|
-- | The maximum integral value that can be unambiguously represented as a
|
||||||
-- 'Float'. Equal to 16,777,215.
|
-- 'Float'. Equal to 16,777,215.
|
||||||
maxFloat :: Num a => a
|
maxFloat :: (Num a) => a
|
||||||
maxFloat = 16777215
|
maxFloat = 16777215
|
||||||
|
|
||||||
-- | The maximum integral value that can be unambiguously represented as a
|
-- | The maximum integral value that can be unambiguously represented as a
|
||||||
-- 'Double'. Equal to 9,007,199,254,740,991.
|
-- 'Double'. Equal to 9,007,199,254,740,991.
|
||||||
maxDouble :: Num a => a
|
maxDouble :: (Num a) => a
|
||||||
maxDouble = 9007199254740991
|
maxDouble = 9007199254740991
|
||||||
|
|
||||||
tryEvaluate :: Exception.Exception e => a -> Either e a
|
tryEvaluate :: (Exception.Exception e) => a -> Either e a
|
||||||
tryEvaluate = Unsafe.unsafePerformIO . Exception.try . Exception.evaluate
|
tryEvaluate = Unsafe.unsafePerformIO . Exception.try . Exception.evaluate
|
||||||
|
@ -30,7 +30,7 @@ as = id
|
|||||||
-- >
|
-- >
|
||||||
-- > -- Prefer this:
|
-- > -- Prefer this:
|
||||||
-- > into @t x
|
-- > into @t x
|
||||||
into :: forall target source. From.From source target => source -> target
|
into :: forall target source. (From.From source target) => source -> target
|
||||||
into = From.from
|
into = From.from
|
||||||
|
|
||||||
-- | This function converts from some @source@ type into some @target@ type,
|
-- | This function converts from some @source@ type into some @target@ type,
|
||||||
@ -78,7 +78,7 @@ via = From.from . (\x -> x :: through) . From.from
|
|||||||
-- > tryInto @t x
|
-- > tryInto @t x
|
||||||
tryInto ::
|
tryInto ::
|
||||||
forall target source.
|
forall target source.
|
||||||
TryFrom.TryFrom source target =>
|
(TryFrom.TryFrom source target) =>
|
||||||
source ->
|
source ->
|
||||||
Either (TryFromException.TryFromException source target) target
|
Either (TryFromException.TryFromException source target) target
|
||||||
tryInto = TryFrom.tryFrom
|
tryInto = TryFrom.tryFrom
|
||||||
@ -136,7 +136,7 @@ maybeTryFrom f s = case f s of
|
|||||||
-- > -- Prefer this:
|
-- > -- Prefer this:
|
||||||
-- > tryFrom = eitherTryFrom f
|
-- > tryFrom = eitherTryFrom f
|
||||||
eitherTryFrom ::
|
eitherTryFrom ::
|
||||||
Exception.Exception exception =>
|
(Exception.Exception exception) =>
|
||||||
(source -> Either exception target) ->
|
(source -> Either exception target) ->
|
||||||
source ->
|
source ->
|
||||||
Either (TryFromException.TryFromException source target) target
|
Either (TryFromException.TryFromException source target) target
|
||||||
|
@ -2453,32 +2453,32 @@ type Spec = Writer.Writer (Seq.Seq HUnit.Test) ()
|
|||||||
anyTryFromException :: Selector (Witch.TryFromException s t)
|
anyTryFromException :: Selector (Witch.TryFromException s t)
|
||||||
anyTryFromException = const True
|
anyTryFromException = const True
|
||||||
|
|
||||||
describe :: Stack.HasCallStack => String -> Spec -> Spec
|
describe :: (Stack.HasCallStack) => String -> Spec -> Spec
|
||||||
describe label = testToSpec . HUnit.TestLabel label . specToTest
|
describe label = testToSpec . HUnit.TestLabel label . specToTest
|
||||||
|
|
||||||
hush :: Either x a -> Maybe a
|
hush :: Either x a -> Maybe a
|
||||||
hush = either (const Nothing) Just
|
hush = either (const Nothing) Just
|
||||||
|
|
||||||
it :: Stack.HasCallStack => String -> HUnit.Assertion -> Spec
|
it :: (Stack.HasCallStack) => String -> HUnit.Assertion -> Spec
|
||||||
it label = testToSpec . HUnit.TestLabel label . HUnit.TestCase
|
it label = testToSpec . HUnit.TestLabel label . HUnit.TestCase
|
||||||
|
|
||||||
shouldBe :: (Stack.HasCallStack, Eq a, Show a) => a -> a -> HUnit.Assertion
|
shouldBe :: (Stack.HasCallStack, Eq a, Show a) => a -> a -> HUnit.Assertion
|
||||||
shouldBe = (HUnit.@?=)
|
shouldBe = (HUnit.@?=)
|
||||||
|
|
||||||
shouldSatisfy :: (Stack.HasCallStack, Show a) => a -> (a -> Bool) -> HUnit.Assertion
|
shouldSatisfy :: (Stack.HasCallStack, Show a) => a -> (a -> Bool) -> HUnit.Assertion
|
||||||
shouldSatisfy value predicate = HUnit.assertBool ("predicate failed on: " ++ show value) $ predicate value
|
shouldSatisfy value predicate = HUnit.assertBool ("predicate failed on: " <> show value) $ predicate value
|
||||||
|
|
||||||
shouldThrow :: (Stack.HasCallStack, Exception.Exception e) => IO a -> Selector e -> HUnit.Assertion
|
shouldThrow :: (Stack.HasCallStack, Exception.Exception e) => IO a -> Selector e -> HUnit.Assertion
|
||||||
shouldThrow action predicate = do
|
shouldThrow action predicate = do
|
||||||
result <- Exception.try action
|
result <- Exception.try action
|
||||||
case result of
|
case result of
|
||||||
Right _ -> HUnit.assertFailure "did not get expected exception"
|
Right _ -> HUnit.assertFailure "did not get expected exception"
|
||||||
Left exception -> HUnit.assertBool ("predicate failed on expected exception: " ++ show exception) $ predicate exception
|
Left exception -> HUnit.assertBool ("predicate failed on expected exception: " <> show exception) $ predicate exception
|
||||||
|
|
||||||
specToTest :: Stack.HasCallStack => Spec -> HUnit.Test
|
specToTest :: (Stack.HasCallStack) => Spec -> HUnit.Test
|
||||||
specToTest = HUnit.TestList . Foldable.toList . Writer.execWriter
|
specToTest = HUnit.TestList . Foldable.toList . Writer.execWriter
|
||||||
|
|
||||||
testToSpec :: Stack.HasCallStack => HUnit.Test -> Spec
|
testToSpec :: (Stack.HasCallStack) => HUnit.Test -> Spec
|
||||||
testToSpec = Writer.tell . Seq.singleton
|
testToSpec = Writer.tell . Seq.singleton
|
||||||
|
|
||||||
unixEpoch :: Time.UTCTime
|
unixEpoch :: Time.UTCTime
|
||||||
|
36
witch.cabal
36
witch.cabal
@ -23,36 +23,27 @@ flag pedantic
|
|||||||
|
|
||||||
common library
|
common library
|
||||||
build-depends:
|
build-depends:
|
||||||
, base >= 4.10 && < 4.18
|
, base >= 4.15 && < 4.18
|
||||||
, bytestring >= 0.10.8 && < 0.12
|
, bytestring >= 0.10.12 && < 0.12
|
||||||
, containers >= 0.5.10 && < 0.7
|
, containers >= 0.6.4 && < 0.7
|
||||||
, tagged >= 0.8.6 && < 0.9
|
, tagged >= 0.8.6 && < 0.9
|
||||||
, text >= 1.2.3 && < 1.3 || >= 2.0 && < 2.1
|
, text >= 1.2.5 && < 1.3 || >= 2.0 && < 2.1
|
||||||
, time >= 1.9.1 && < 1.13
|
, time >= 1.9.3 && < 1.13
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
ghc-options:
|
ghc-options:
|
||||||
-Weverything
|
-Weverything
|
||||||
-Wno-all-missed-specialisations
|
-Wno-all-missed-specialisations
|
||||||
-Wno-implicit-prelude
|
-Wno-implicit-prelude
|
||||||
-Wno-missed-specialisations
|
-Wno-missed-specialisations
|
||||||
|
-Wno-missing-deriving-strategies
|
||||||
|
-Wno-missing-export-lists
|
||||||
-Wno-missing-exported-signatures
|
-Wno-missing-exported-signatures
|
||||||
|
-Wno-missing-safe-haskell-mode
|
||||||
|
-Wno-prepositive-qualified-module
|
||||||
-Wno-redundant-constraints
|
-Wno-redundant-constraints
|
||||||
-Wno-safe
|
-Wno-safe
|
||||||
-Wno-unsafe
|
-Wno-unsafe
|
||||||
|
|
||||||
if impl(ghc >= 8.4)
|
|
||||||
ghc-options:
|
|
||||||
-Wno-missing-export-lists
|
|
||||||
|
|
||||||
if impl(ghc >= 8.8)
|
|
||||||
ghc-options:
|
|
||||||
-Wno-missing-deriving-strategies
|
|
||||||
|
|
||||||
if impl(ghc >= 8.10)
|
|
||||||
ghc-options:
|
|
||||||
-Wno-missing-safe-haskell-mode
|
|
||||||
-Wno-prepositive-qualified-module
|
|
||||||
|
|
||||||
if impl(ghc >= 9.2)
|
if impl(ghc >= 9.2)
|
||||||
ghc-options:
|
ghc-options:
|
||||||
-Wno-missing-kind-signatures
|
-Wno-missing-kind-signatures
|
||||||
@ -73,7 +64,7 @@ library
|
|||||||
import: library
|
import: library
|
||||||
|
|
||||||
build-depends:
|
build-depends:
|
||||||
, template-haskell >= 2.12 && < 2.20
|
, template-haskell >= 2.17 && < 2.20
|
||||||
exposed-modules:
|
exposed-modules:
|
||||||
Witch
|
Witch
|
||||||
Witch.Encoding
|
Witch.Encoding
|
||||||
@ -85,13 +76,6 @@ library
|
|||||||
Witch.Utility
|
Witch.Utility
|
||||||
hs-source-dirs: source/library
|
hs-source-dirs: source/library
|
||||||
|
|
||||||
if impl(ghc >= 9.0)
|
|
||||||
hs-source-dirs: source/ghc-9.0
|
|
||||||
elif impl(ghc >= 8.10)
|
|
||||||
hs-source-dirs: source/ghc-8.10
|
|
||||||
else
|
|
||||||
hs-source-dirs: source/ghc-8.8
|
|
||||||
|
|
||||||
test-suite witch-test-suite
|
test-suite witch-test-suite
|
||||||
import: executable
|
import: executable
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user