Add initial files

This commit is contained in:
Nathan McRae
2025-07-14 18:21:18 -07:00
commit 60a0cc74a3
5 changed files with 283 additions and 0 deletions

10
.gitignore vendored Normal file
View File

@@ -0,0 +1,10 @@
/bower_components/
/node_modules/
/.pulp-cache/
/output/
/generated-docs/
/.psc-package/
/.psc*
/.purs*
/.psa*
/.spago

105
packages.dhall Normal file
View File

@@ -0,0 +1,105 @@
{-
Welcome to your new Dhall package-set!
Below are instructions for how to edit this file for most use
cases, so that you don't need to know Dhall to use it.
## Use Cases
Most will want to do one or both of these options:
1. Override/Patch a package's dependency
2. Add a package not already in the default package set
This file will continue to work whether you use one or both options.
Instructions for each option are explained below.
### Overriding/Patching a package
Purpose:
- Change a package's dependency to a newer/older release than the
default package set's release
- Use your own modified version of some dependency that may
include new API, changed API, removed API by
using your custom git repo of the library rather than
the package set's repo
Syntax:
where `entityName` is one of the following:
- dependencies
- repo
- version
-------------------------------
let upstream = --
in upstream
with packageName.entityName = "new value"
-------------------------------
Example:
-------------------------------
let upstream = --
in upstream
with halogen.version = "master"
with halogen.repo = "https://example.com/path/to/git/repo.git"
with halogen-vdom.version = "v4.0.0"
with halogen-vdom.dependencies = [ "extra-dependency" ] # halogen-vdom.dependencies
-------------------------------
### Additions
Purpose:
- Add packages that aren't already included in the default package set
Syntax:
where `<version>` is:
- a tag (i.e. "v4.0.0")
- a branch (i.e. "master")
- commit hash (i.e. "701f3e44aafb1a6459281714858fadf2c4c2a977")
-------------------------------
let upstream = --
in upstream
with new-package-name =
{ dependencies =
[ "dependency1"
, "dependency2"
]
, repo =
"https://example.com/path/to/git/repo.git"
, version =
"<version>"
}
-------------------------------
Example:
-------------------------------
let upstream = --
in upstream
with benchotron =
{ dependencies =
[ "arrays"
, "exists"
, "profunctor"
, "strings"
, "quickcheck"
, "lcg"
, "transformers"
, "foldable-traversable"
, "exceptions"
, "node-fs"
, "node-buffer"
, "node-readline"
, "datetime"
, "now"
]
, repo =
"https://github.com/hdgarrood/purescript-benchotron.git"
, version =
"v7.0.0"
}
-------------------------------
-}
let upstream =
https://github.com/purescript/package-sets/releases/download/psc-0.15.15-20250622/packages.dhall
sha256:2d1b91988594be9ec99cee86ca4f0a85efe36d51fd24cb1305b27a9611406e13
in upstream

26
spago.dhall Normal file
View File

@@ -0,0 +1,26 @@
{-
Welcome to a Spago project!
You can edit this file as you like.
Need help? See the following resources:
- Spago documentation: https://github.com/purescript/spago
- Dhall language tour: https://docs.dhall-lang.org/tutorials/Language-Tour.html
When creating a new Spago project, you can use
`spago init --no-comments` or `spago init -C`
to generate this file without the comments in this block.
-}
{ name = "my-project"
, dependencies =
[ "arrays"
, "console"
, "effect"
, "integers"
, "lists"
, "numbers"
, "prelude"
, "tuples"
]
, packages = ./packages.dhall
, sources = [ "src/**/*.purs", "test/**/*.purs" ]
}

131
src/Main.purs Normal file
View File

@@ -0,0 +1,131 @@
module Main where
import Prelude (discard, class Monoid, class Semigroup, Unit, ($), (<>), (>>>))
import Data.Array (range, cons)
import Data.Field (div)
import Data.Functor (map)
import Data.Int (toNumber)
import Data.Number (cos, pi, sin)
import Data.Number.Format (toString)
import Data.List (fold)
import Data.Ord ((<))
import Data.Ring (add, mul, negate, sub)
import Data.Tuple.Nested (Tuple3, tuple3, get1, get2, get3)
import Effect (Effect)
import Effect.Console (log)
type Point =
{ x :: Number
, y :: Number
}
type Line =
{ start :: Point
, end :: Point
}
-- TODO: How to do more normal math expressions?
rotate :: Number -> Point -> Point
rotate angle { x: x, y: y} = {
x: sub (mul (cos angle) x) (mul (sin angle) y),
y: add (mul (sin angle) x) (mul (cos angle) y)
}
transform :: Number -> Number -> Number -> Point -> Point
transform scale xOffset yOffset { x: x, y: y} = {
x: (add (mul scale x) xOffset),
y: (add (mul scale y) yOffset)
}
rotateLine :: Number -> Line -> Line
rotateLine angle { start: p1, end: p2} = {
start: rotate angle p1,
end: rotate angle p2
}
transformLine :: Number -> Number -> Number -> Line -> Line
transformLine scale xOffset yOffset { start: start, end: end } = {
start : t start,
end : t end
}
where t = transform scale xOffset yOffset
-- How to handle the different coordinate systems?
-- These things should be generated in the basic coordinate system
-- * ticks via generateTicks
-- * axis labels
-- * axis lines
-- There should be a transform function that these should be passed through directly after generation
newtype XMLFragment = XMLFragment String
derive newtype instance xmlFragmentSemiGroup :: Semigroup XMLFragment
derive newtype instance xmlFragmentMonoid :: Monoid XMLFragment
-- TODO: Add style configuration
svgLine :: Line -> XMLFragment
svgLine { start: {x: x1, y: y1}, end: {x: x2, y: y2} } =
XMLFragment $ """<path style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
""" <> (toString x1) <> "," <> (toString y1) <> " " <> (toString x2) <> "," <> (toString y2) <> "\"/>"
-- TODO: Make axis tick size a parameter
getTick :: Number -> Int -> Int -> Line
getTick scale numTicks tickI =
{start: {x: x, y: negate (add 0.5 (div 5.0 scale))}, end: {x: x, y: y}}
where
x = (sub (div (mul 2.0 (mul (sin (div pi 3.0)) (toNumber tickI))) (toNumber numTicks)) (sin (div pi 3.0)))
y = if tickI < (div numTicks 2)
then (add 1.0 (mul x (div 1.5 (sin (div pi 3.0)))))
else (sub 1.0 (mul x (div 1.5 (sin (div pi 3.0)))))
getTicks :: Number -> Number -> Int -> Tuple3 (Array Line) (Array Line) (Array Line)
getTicks scale angle numTicks = --tuple3 [] [] []
tuple3 axis1Lines axis2Lines axis3Lines
where
foo = map (getTick scale numTicks) (range 0 numTicks)
axis1Lines = map (rotateLine angle) foo
axis2Lines = map (rotateLine (mul 2.0 (div pi 3.0))) axis1Lines
axis3Lines = map (rotateLine (mul 2.0 (div pi 3.0))) axis2Lines
-- There's probably a better way to do this
unfragment :: XMLFragment -> String
unfragment (XMLFragment frag) = frag
ternaryGraphSvg :: Array XMLFragment -> String
ternaryGraphSvg fragments = """<?xml version="1.0" encoding="UTF-8"?>
<svg
width="150mm"
height="120mm"
viewBox="-50 -50 200 200"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:svg="http://www.w3.org/2000/svg">
""" <> unfragment (fold fragments) <> "</svg>"
axesPoints :: Number -> Array Point
axesPoints angle = [
rotate angle { x: 0, y: 1 },
rotate angle { x: (negate (sin (mul 2.0 (div pi 3.0)))), y : (negate 0.5)},
rotate angle { x: (sin (mul (div pi 3.0))), y: (negate 0.5) }
]
ternaryGraph :: Number -> Number -> Number -> Int -> String
ternaryGraph scale xOffset yOffset numTicks = ternaryGraphSvg [tickLinesSvg, axesPathSvg, axisTitleSvg, tickLabelsSvg]
where
axisTickLines = getTicks scale pi numTicks
axis1TickLines = get1 axisTickLines
axis2TickLines = get2 axisTickLines
axis3TickLines = get3 axisTickLines
tickLines = (cons axis1TickLines (cons axis2TickLines axis3TickLines))
transformMyLine = transformLine scale xOffset yOffset
tickLinesSvg = fold $ map (svgLine >>> transformMyLine) tickLines
axesPathSvg =
main :: Effect Unit
main = do
log $ ternaryGraphSvg [XMLFragment "<asdf/>", XMLFragment "<foobar/>"]
log $ toString $ toNumber (div 5 3)

11
test/Main.purs Normal file
View File

@@ -0,0 +1,11 @@
module Test.Main where
import Prelude
import Effect (Effect)
import Effect.Class.Console (log)
main :: Effect Unit
main = do
log "🍝"
log "You should add some tests."