zwirn-0.2.2.0: src/zwirn-lang/Zwirn/Language/Builtin/Prelude.hs
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -Wno-orphans #-}
module Zwirn.Language.Builtin.Prelude where
{-
Builtin.hs - defines builtin functions
Copyright (C) 2023, Martin Gius
This library is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library. If not, see <http://www.gnu.org/licenses/>.
-}
import qualified Data.Map as Map
import Data.Text (Text)
import Zwirn.Core.Lib.Conditional as Z
import Zwirn.Core.Lib.Cord as C
import Zwirn.Core.Lib.Core as C
import Zwirn.Core.Lib.Map as M
import Zwirn.Core.Lib.Modulate
import Zwirn.Core.Lib.Number as N
import Zwirn.Core.Lib.Random
import Zwirn.Core.Lib.Structure as S
import Zwirn.Core.Time
import Zwirn.Language.Builtin.Internal
import Zwirn.Language.Builtin.Parameters
import Zwirn.Language.Environment
import Zwirn.Language.Evaluate hiding (insert)
import Zwirn.Language.TypeCheck.Types
import Zwirn.Stream.Types (Stream)
builtinEnvironment :: InterpreterEnv
builtinEnvironment = IEnv builtins instances
builtinEnvironmentWithStream :: Stream -> InterpreterEnv
builtinEnvironmentWithStream str = IEnv (Map.unions [builtins, streamFunctions str]) instances
instances :: [Instance]
instances =
[ IsIn "Num" numberT,
IsIn "Num" mapT,
IsIn "Eq" numberT,
IsIn "Eq" mapT,
IsIn "Eq" textT,
IsIn "Id" numberT,
IsIn "Id" textT,
IsIn "Id" mapT
]
builtinNames :: [Text]
builtinNames = Map.keys builtins
builtins :: Map.Map Text AnnotatedExpression
builtins =
Map.unions
[ coreFunctions,
numberFunctions,
signals,
randomFunctions,
timeFunctions,
structureFunctions,
conditionalFunctions,
cordFunctions,
mapFunctions,
builtinParams,
noteExpressions,
chordExpressions
]
coreFunctions :: Map.Map Text AnnotatedExpression
coreFunctions =
Map.unions
[ "id"
=== lambda id
<:: "a -> a"
--| "identity function",
"const"
=== lambda (lambda . const)
<:: "a -> b -> a"
--| "constant function - ignore second input",
"scomb"
=== lambda (\f -> lambda $ \g -> lambda $ \x -> f ! x ! (g ! x))
<:: "(a -> b -> c) -> (a -> b) -> a -> c"
--| "S-combinator",
"(.)"
=== lambda (\g -> lambda $ \f -> lambda $ \x -> g ! (f ! x))
<:: "(b -> c) -> (a -> b) -> a -> c"
--| "function composition",
"flip"
=== lambda (\f -> lambda $ \y -> lambda $ \x -> f ! x ! y)
<:: "(a -> b -> c) -> b -> a -> c"
--| "flip arguments",
"(\')"
=== toExp (flip apply :: Zwirn Expression -> Zwirn (Zwirn Expression -> Zwirn Expression) -> Zwirn Expression)
<:: "a -> (a -> b) -> b"
--| "apply argument to function, results are squeezed and zipped",
"($)"
=== toExp (apply :: Zwirn (Zwirn Expression -> Zwirn Expression) -> Zwirn Expression -> Zwirn Expression)
<:: "(a -> b) -> a -> b"
--| "apply function to argument, results are squeezed and zipped",
"match"
=== toExp (matchApply :: Zwirn (Zwirn Expression -> Zwirn Expression) -> Zwirn Expression -> Zwirn Expression)
<:: "(a -> b) -> a -> b"
--| "",
"iterate"
=== toExp (C.iterate :: Zwirn Int -> Zwirn (Zwirn Expression -> Zwirn Expression) -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> (a -> a) -> a -> a"
--| "apply function to argument, n times",
"(|$)"
=== toExp (outerApply :: Zwirn (Zwirn Expression -> Zwirn Expression) -> Zwirn Expression -> Zwirn Expression)
<:: "(a -> b) -> a -> b"
--| "apply function to argument",
"($|)"
=== toExp (innerApply :: Zwirn (Zwirn Expression -> Zwirn Expression) -> Zwirn Expression -> Zwirn Expression)
<:: "(a -> b) -> a -> b"
--| "apply function to argument",
"squeeze"
=== toExp (squeeze :: Zwirn (Zwirn Expression -> Zwirn Expression) -> Zwirn Expression -> Zwirn Expression)
<:: "(a -> b) -> a -> b"
--| "map a function over the structure of the argument",
"inner"
=== toExp (getInnerTime :: Zwirn Expression -> Zwirn Double)
<:: "a -> Number"
--| "get the inner time of a zwirn",
"diff"
=== toExp (getSpeed :: Zwirn Expression -> Zwirn Double)
<:: "a -> Number"
--| "get the speed of a zwirn",
"trig"
=== toExp (trig :: Zwirn Expression -> Zwirn Bool)
<:: "a -> Number"
--| "returns true on the trigger points, false otherwise",
"recv"
=== toExp recv
<:: "(Number -> Map) -> Number -> Map"
--| "recieve a value from a bus and send it to the given parameter",
"recvT"
=== toExp recvT
<:: "Text -> Number -> Map"
--| "like recv but takes the parameter name as text"
]
numberFunctions :: Map.Map Text AnnotatedExpression
numberFunctions =
Map.unions
[ "(|+)"
=== toExp ((+) :: Zwirn Expression -> Zwirn Expression -> Zwirn Expression)
<:: "Num a => a -> a -> a"
--| "addition",
"(|-)"
=== toExp ((-) :: Zwirn Expression -> Zwirn Expression -> Zwirn Expression)
<:: "Num a => a -> a -> a"
--| "subtraction",
"(|*)"
=== toExp ((*) :: Zwirn Expression -> Zwirn Expression -> Zwirn Expression)
<:: "Num a => a -> a -> a"
--| "multiplication",
"(|/)"
=== toExp ((/) :: Zwirn Expression -> Zwirn Expression -> Zwirn Expression)
<:: "Num a => a -> a -> a"
--| "division",
"negate"
=== toExp (negate :: Zwirn Expression -> Zwirn Expression)
<:: "Num a => a -> a"
--| "negate",
"abs"
=== toExp (abs :: Zwirn Expression -> Zwirn Expression)
<:: "Num a => a -> a"
--| "absolute value",
"signum"
=== toExp (signum :: Zwirn Expression -> Zwirn Expression)
<:: "Num a => a -> a"
--| "signum",
"recip"
=== toExp (recip :: Zwirn Expression -> Zwirn Expression)
<:: "Num a => a -> a"
--| "reciprocal value",
"pi"
=== toExp (pi :: Zwirn Expression)
<:: "Number"
--| "pi",
"(|**)"
=== toExp ((**) :: Zwirn Expression -> Zwirn Expression -> Zwirn Expression)
<:: "Num a => a -> a -> a"
--| "exponentiation",
"exp"
=== toExp (exp :: Zwirn Expression -> Zwirn Expression)
<:: "Num a => a -> a"
--| "exponential function",
"log"
=== toExp (log :: Zwirn Expression -> Zwirn Expression)
<:: "Num a => a -> a"
--| "logarithm base 10",
"sqrt"
=== toExp (sqrt :: Zwirn Expression -> Zwirn Expression)
<:: "Num a => a -> a"
--| "square root",
"sin"
=== toExp (sin :: Zwirn Expression -> Zwirn Expression)
<:: "Num a => a -> a"
--| "sine function",
"cos"
=== toExp (cos :: Zwirn Expression -> Zwirn Expression)
<:: "Num a => a -> a"
--| "cosine function",
"tan"
=== toExp (tan :: Zwirn Expression -> Zwirn Expression)
<:: "Num a => a -> a"
--| "tangens",
"asin"
=== toExp (asin :: Zwirn Expression -> Zwirn Expression)
<:: "Num a => a -> a"
--| "arc sine function",
"acos"
=== toExp (acos :: Zwirn Expression -> Zwirn Expression)
<:: "Num a => a -> a"
--| "arc cosine function",
"atan"
=== toExp (atan :: Zwirn Expression -> Zwirn Expression)
<:: "Num a => a -> a"
--| "arc tangens",
"sinh"
=== toExp (sinh :: Zwirn Expression -> Zwirn Expression)
<:: "Num a => a -> a"
--| "hyperbolic sine",
"cosh"
=== toExp (cosh :: Zwirn Expression -> Zwirn Expression)
<:: "Num a => a -> a"
--| "hyperbolic cosine",
"tanh"
=== toExp (tan :: Zwirn Expression -> Zwirn Expression)
<:: "Num a => a -> a"
--| "hyperbolic tangens",
"asinh"
=== toExp (asinh :: Zwirn Expression -> Zwirn Expression)
<:: "Num a => a -> a"
--| "hyperbolic arc sine function",
"acosh"
=== toExp (acosh :: Zwirn Expression -> Zwirn Expression)
<:: "Num a => a -> a"
--| "hyperbolic arc cosine function",
"atanh"
=== toExp (atanh :: Zwirn Expression -> Zwirn Expression)
<:: "Num a => a -> a"
--| "hyperbolic arc tangens",
"mod"
=== toExp (N.mod :: Zwirn Double -> Zwirn Double -> Zwirn Double)
<:: "Number -> Number -> Number"
--| "modulo",
"frac"
=== toExp (N.frac :: Zwirn Double -> Zwirn Double)
<:: "Number -> Number"
--| "fractional part of a number",
"trunc"
=== toExp (N.trunc :: Zwirn Double -> Zwirn Int)
<:: "Number -> Number"
--| "truncate",
"ceil"
=== toExp (N.ceil :: Zwirn Double -> Zwirn Int)
<:: "Number -> Number"
--| "round up",
"floor"
=== toExp (N.floor :: Zwirn Double -> Zwirn Int)
<:: "Number -> Number"
--| "round down",
"round"
=== toExp (N.round :: Zwirn Double -> Zwirn Int)
<:: "Number -> Number"
--| "round to closest",
"gcd"
=== toExp (N.gcd :: Zwirn Int -> Zwirn Int -> Zwirn Int)
<:: "Number -> Number -> Number"
--| "greatest common divisor",
"lcm"
=== toExp (N.lcm :: Zwirn Int -> Zwirn Int -> Zwirn Int)
<:: "Number -> Number -> Number"
--| "least common multiple",
"range"
=== toExp (range :: Zwirn Double -> Zwirn Double -> Zwirn Double -> Zwirn Double)
<:: "Number -> Number -> Number -> Number"
--| "range x y l maps number l linearly into interval (x,y), assuming l is between 0 and 1"
]
signals :: Map.Map Text AnnotatedExpression
signals =
Map.unions
[ "now"
=== toExp (now :: Zwirn Time)
<:: "Number"
--| "current time",
"cyc"
=== toExp (C.cyc :: Zwirn Int)
<:: "Number"
--| "current cycle",
"sine"
=== toExp (sine :: Zwirn Time)
<:: "Number"
--| "sine signal",
"sine2"
=== toExp (sine2 :: Zwirn Time)
<:: "Number"
--| "bipolar sine signal",
"saw"
=== toExp (saw :: Zwirn Time)
<:: "Number"
--| "saw signal",
"saw2"
=== toExp (saw2 :: Zwirn Time)
<:: "Number"
--| "bipolar saw signal",
"cosine"
=== toExp (cosine :: Zwirn Time)
<:: "Number"
--| "cosine signal",
"cosine2"
=== toExp (cosine2 :: Zwirn Time)
<:: "Number"
--| "bipolar cosine signal",
"isaw"
=== toExp (isaw :: Zwirn Time)
<:: "Number"
--| "inverse saw signal",
"isaw2"
=== toExp (isaw2 :: Zwirn Time)
<:: "Number"
--| "bipolar inverse saw signal",
"tri"
=== toExp (tri :: Zwirn Time)
<:: "Number"
--| "triangle signal",
"tri2"
=== toExp (tri2 :: Zwirn Time)
<:: "Number"
--| "bipolar triangle signal",
"square"
=== toExp (square :: Zwirn Time)
<:: "Number"
--| "square signal",
"square2"
=== toExp (square2 :: Zwirn Time)
<:: "Number"
--| "bipolar square signal",
"firstCyclesThen"
=== toExp (firstCyclesThen :: Zwirn Time -> Zwirn Expression -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> a -> a -> a"
--| "bipolar square signal"
]
randomFunctions :: Map.Map Text AnnotatedExpression
randomFunctions =
Map.unions
[ "rand"
=== toExp (noise :: Zwirn Double)
<:: "Number"
--| "random stream of values between 0 and 1",
"brand"
=== toExp (rand :: Zwirn Bool)
<:: "Number"
--| "random binary choice",
"brandBy"
=== toExp (brandBy :: Zwirn Double -> Zwirn Bool)
<:: "Number -> Number"
--| "weighted random binary choice",
"irand"
=== toExp (irand :: Zwirn Int -> Zwirn Int)
<:: "Number -> Number"
--| "random integer values between 0 and given input",
"cycrand"
=== toExp (rand' :: Zwirn Double)
<:: "Number"
--| "random stream of values between 0 and 1, one value per cycle",
"cycbrand"
=== toExp (rand :: Zwirn Bool)
<:: "Number"
--| "random binary cyclewise choice",
"cycbrandBy"
=== toExp (brandBy' :: Zwirn Double -> Zwirn Bool)
<:: "Number -> Number"
--| "weighted random binary cyclewise choice",
"cycirand"
=== toExp (irand' :: Zwirn Int -> Zwirn Int)
<:: "Number -> Number"
--| "random integer values between 0 and given input, one value per cycle",
"perlin"
=== toExp (perlin :: Zwirn Double)
<:: "Number"
--| "perlin noise between 0 and 1",
"simplex"
=== toExp (simplex :: Zwirn Double)
<:: "Number"
--| "simplex noise between 0 and 1",
"ssimplex"
=== toExp (ssimplex :: Zwirn Double)
<:: "Number"
--| "super simplex noise between 0 and 1",
"value"
=== toExp (valueN :: Zwirn Double)
<:: "Number"
--| "value noise between 0 and 1",
"cubic"
=== toExp (cubic :: Zwirn Double)
<:: "Number"
--| "cubic value noise between 0 and 1",
"perlinS"
=== toExp (perlinSeed :: Zwirn Int -> Zwirn Double)
<:: "Number -> Number"
--| "seeded perlin noise between 0 and 1",
"simplexS"
=== toExp (simplexSeed :: Zwirn Int -> Zwirn Double)
<:: "Number -> Number"
--| "seeded simplex noise between 0 and 1",
"ssimplexS"
=== toExp (ssimplexSeed :: Zwirn Int -> Zwirn Double)
<:: "Number -> Number"
--| "seeded super simplex noise between 0 and 1",
"valueS"
=== toExp (valueSeed :: Zwirn Int -> Zwirn Double)
<:: "Number -> Number"
--| "seeded value noise between 0 and 1",
"cubicS"
=== toExp (cubicSeed :: Zwirn Int -> Zwirn Double)
<:: "Number -> Number"
--| "seeded cubic value noise between 0 and 1",
"somecyclesBy"
=== toExp (somecyclesBy :: Zwirn Double -> Zwirn (Zwirn Expression -> Zwirn Expression) -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> (a -> b) -> a -> b"
--| "apply a function with a given chance per cycle",
"somecycles"
=== toExp (somecycles :: Zwirn (Zwirn Expression -> Zwirn Expression) -> Zwirn Expression -> Zwirn Expression)
<:: "(a -> b) -> a -> b"
--| "apply a functions with a 50% chance per cycle",
"sometimesBy"
=== toExp (sometimesBy :: Zwirn Double -> Zwirn (Zwirn Expression -> Zwirn Expression) -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> (a -> b) -> a -> b"
--| "apply a function with a given chance",
"sometimes"
=== toExp (sometimes :: Zwirn (Zwirn Expression -> Zwirn Expression) -> Zwirn Expression -> Zwirn Expression)
<:: "(a -> b) -> a -> b"
--| "apply a function with a 50% chance",
"often"
=== toExp (often :: Zwirn (Zwirn Expression -> Zwirn Expression) -> Zwirn Expression -> Zwirn Expression)
<:: "(a -> b) -> a -> b"
--| "apply a function with a 75% chance",
"rarely"
=== toExp (rarely :: Zwirn (Zwirn Expression -> Zwirn Expression) -> Zwirn Expression -> Zwirn Expression)
<:: "(a -> b) -> a -> b"
--| "apply a function with a 25% chance",
"almostNever"
=== toExp (almostNever :: Zwirn (Zwirn Expression -> Zwirn Expression) -> Zwirn Expression -> Zwirn Expression)
<:: "(a -> b) -> a -> b"
--| "apply a function with a 10% chance",
"almostAlways"
=== toExp (almostNever :: Zwirn (Zwirn Expression -> Zwirn Expression) -> Zwirn Expression -> Zwirn Expression)
<:: "(a -> b) -> a -> b"
--| "apply a function with a 90% chance",
"chooseFromTo"
=== toExp (enumFromToChoice 0 :: Zwirn Double -> Zwirn Double -> Zwirn Double)
<:: "Number -> Number -> Number"
--| "```chooseFromTo x y == [x | .. y]```",
"chooseFromThenTo"
=== toExp (enumFromThenToChoice 0 :: Zwirn Double -> Zwirn Double -> Zwirn Double -> Zwirn Double)
<:: "Number -> Number -> Number -> Number"
--| "```chooseFromTo x y z == [x | y .. z]```"
]
timeFunctions :: Map.Map Text AnnotatedExpression
timeFunctions =
Map.unions
[ "(*)"
=== toExp (flip fast :: Zwirn Expression -> Zwirn Time -> Zwirn Expression)
<:: "a -> Number -> a"
--| "multiply time, making it faster",
"fast"
=== toExp (fast :: Zwirn Time -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> a -> a"
--| "multiply time, making it faster",
"(/)"
=== toExp (flip slow :: Zwirn Expression -> Zwirn Time -> Zwirn Expression)
<:: "a -> Number -> a"
--| "divide time, making it slower",
"slow"
=== toExp (slow :: Zwirn Time -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> a -> a"
--| "divide time, making it slower",
"(+)"
=== toExp (flip shift :: Zwirn Expression -> Zwirn Time -> Zwirn Expression)
<:: "a -> Number -> a"
--| "shift time to the right",
"(-)"
=== toExp (flip (shift . fmap negate) :: Zwirn Expression -> Zwirn Time -> Zwirn Expression)
<:: "a -> Number -> a"
--| "shift time to the left",
"shift"
=== toExp (shift :: Zwirn Time -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> a -> a"
--| "shift time",
"revBy"
=== toExp (revBy :: Zwirn Time -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> a -> a"
--| "reverse time, piecewise",
"rev"
=== toExp (rev :: Zwirn Expression -> Zwirn Expression)
<:: "a -> a"
--| "reverse time completely",
"ply"
=== toExp (ply :: Zwirn Time -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> a -> a"
--| "speed up time inside",
"bump"
=== toExp (bump :: Zwirn Time -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> a -> a"
--| "shift time inside",
"timeloop"
=== toExp (timeloop :: Zwirn Time -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> a -> a"
--| "loop time from 0 to the given number",
"loop"
=== toExp (loop :: Zwirn Time -> Zwirn Time -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> Number -> a -> a"
--| "loop a specifc range of a zwirn, speeding up",
"ribbon"
=== toExp (ribbon :: Zwirn Time -> Zwirn Time -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> Number -> a -> a"
--| "given an offset and a length, loops the according region",
"zoom"
=== toExp (zoom :: Zwirn Time -> Zwirn Time -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> Number -> a -> a"
--| "zoom and loop a part of a zwirn",
"swingBy"
=== toExp (swingBy :: Zwirn Time -> Zwirn Time -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> Number -> a -> a"
--| "given a swing amount and a number of subdivisions, shifts the second half of every subdivion by the given amount, creating a swing feel."
]
structureFunctions :: Map.Map Text AnnotatedExpression
structureFunctions =
Map.unions
[ "euclidOff"
=== toExp (euclidOff :: Zwirn Int -> Zwirn Int -> Zwirn Int -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> Number -> Number -> a -> a"
--| "shifted euclidean rhythm",
"euclid"
=== toExp (euclid :: Zwirn Int -> Zwirn Int -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> Number -> a -> a"
--| "euclidean rhythm",
"euclideanOff"
=== toExp (euclidean :: Zwirn Int -> Zwirn Int -> Zwirn Int -> Zwirn String)
<:: "Number -> Number -> Number -> Text"
--| "string representation of shifted euclidean rhythm",
"euclidean"
=== toExp ((euclidean $ pure 0) :: Zwirn Int -> Zwirn Int -> Zwirn String)
<:: "Number -> Number -> Number -> Text"
--| "string representation of euclidean rhythm",
"binary"
=== toExp (binary :: Zwirn Int -> Zwirn String)
<:: "Number -> Text"
--| "converts number to binary sequence",
"christoffel"
=== toExp (christoffel :: Zwirn Int -> Zwirn Int -> Zwirn String)
<:: "Number -> Number -> Text"
--| "create the two alphabet christoffel word",
"neg"
=== toExp (neg :: Zwirn String -> Zwirn String)
<:: "Text -> Text"
--| "make onsets to offsets in chunk notation",
-- "rotate"
-- === toExp (rotate :: Zwirn Int -> Zwirn String -> Zwirn String)
-- <:: "Number -> Text -> Text"
-- --| "rotate characters in a string by amount",
"chunkWith"
=== toExp (chunkWith :: Zwirn Double -> Zwirn String -> Zwirn Int)
<:: "Number -> Text -> Number"
--| "converts from Boenn's chunk notation to a rhythm",
"chunk"
=== toExp (chunk :: Zwirn String -> Zwirn Int)
<:: "Text -> Number"
--| "converts from Boenn's chunk notation to a rhythm",
"chunked"
=== toExp (chunked :: Zwirn String -> Zwirn Expression -> Zwirn Expression)
<:: "Text -> a -> a"
--| "converts from Boenn's chunk notation to a rhythm",
"segment"
=== toExp (segment :: Zwirn Int -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> a -> a"
--| "divide structure into equal pieces",
"sample"
=== toExp (sampleAndHold :: Zwirn Int -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> a -> a"
--| "like segment, but the values are held ('sample and hold')",
"struct"
=== toExp (struct :: Zwirn Expression -> Zwirn Expression -> Zwirn Expression)
<:: "a -> b -> b"
--| "copy the structure from first value",
"run"
=== toExp (run :: Zwirn Int -> Zwirn Int)
<:: "Number -> Number"
--| "```run n == [0 .. n-1]```",
"runFromTo"
=== toExp (runFromTo :: Zwirn Double -> Zwirn Double -> Zwirn Double)
<:: "Number -> Number -> Number"
--| "```runFromTo x y == [x .. y]```",
"runFromThenTo"
=== toExp (runFromThenTo :: Zwirn Double -> Zwirn Double -> Zwirn Double -> Zwirn Double)
<:: "Number -> Number -> Number -> Number"
--| "```runFromTo x y z == [x y .. z]```",
"slowrun"
=== toExp (slowrun :: Zwirn Int -> Zwirn Int)
<:: "Number -> Number"
--| "```run n == <0 .. n-1>```",
"slowrunFromTo"
=== toExp (slowrunFromTo :: Zwirn Double -> Zwirn Double -> Zwirn Double)
<:: "Number -> Number -> Number"
--| "```slowrunFromTo x y == <x .. y>```",
"slowrunFromThenTo"
=== toExp (slowrunFromThenTo :: Zwirn Double -> Zwirn Double -> Zwirn Double -> Zwirn Double)
<:: "Number -> Number -> Number -> Number"
--| "```slowrunFromTo x y z == <x y .. z>```"
]
conditionalFunctions :: Map.Map Text AnnotatedExpression
conditionalFunctions =
Map.unions
[ "(==)"
=== toExp (eq :: Zwirn Expression -> Zwirn Expression -> Zwirn Bool)
<:: "Eq a => a -> a -> Number"
--| "equality",
"(>=)"
=== toExp (geq :: Zwirn Expression -> Zwirn Expression -> Zwirn Bool)
<:: "Number -> Number -> Number"
--| "greater or equal",
"(<=)"
=== toExp (leq :: Zwirn Expression -> Zwirn Expression -> Zwirn Bool)
<:: "Number -> Number -> Number"
--| "less or equal",
"(<)"
=== toExp (ge :: Zwirn Expression -> Zwirn Expression -> Zwirn Bool)
<:: "Number -> Number -> Number"
--| "less",
"(>)"
=== toExp (le :: Zwirn Expression -> Zwirn Expression -> Zwirn Bool)
<:: "Number -> Number -> Number"
--| "greater",
"not"
=== toExp (Z.not :: Zwirn Bool -> Zwirn Bool)
<:: "Number -> Number"
--| "logical not",
"(&&)"
=== toExp (Z.and :: Zwirn Bool -> Zwirn Bool -> Zwirn Bool)
<:: "Number -> Number -> Number"
--| "logical and",
"(||)"
=== toExp (Z.or :: Zwirn Bool -> Zwirn Bool -> Zwirn Bool)
<:: "Number -> Number -> Number"
--| "logical or",
"ifthen"
=== toExp (ifthen :: Zwirn Bool -> Zwirn Expression -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> a -> a -> a"
--| "choose between two expressions based on a condition",
"if"
=== toExp (iff :: Zwirn Bool -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> a -> a"
--| "if condition is true produce the value, silence otherwise",
"while"
=== toExp (while :: Zwirn Bool -> Zwirn (Zwirn Expression -> Zwirn Expression) -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> (a -> a) -> a -> a"
--| "apply function while condition is true",
"everyFor"
=== toExp (everyFor :: Zwirn Time -> Zwirn Time -> Zwirn (Zwirn Expression -> Zwirn Expression) -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> Number -> (a -> a) -> a -> a"
--| "apply function periodically for a given amount of time",
"every"
=== toExp (every :: Zwirn Time -> Zwirn (Zwirn Expression -> Zwirn Expression) -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> (a -> a) -> a -> a"
--| "apply function periodically for one cycle",
"everyBeat"
=== toExp (everyBeat :: Zwirn Time -> Zwirn (Zwirn Expression -> Zwirn Expression) -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> (a -> a) -> a -> a"
--| "apply function every nth beat",
"everyBeatShift"
=== toExp (everyBeatShift :: Zwirn Time -> Zwirn Time -> Zwirn (Zwirn Expression -> Zwirn Expression) -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> Number -> (a -> a) -> a -> a"
--| "apply function every nth beat, shifted in time"
]
cordFunctions :: Map.Map Text AnnotatedExpression
cordFunctions =
Map.unions
[ "pick"
=== toExp (pick :: Zwirn Int -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> a -> a"
--| "pick a certain layer of a cord using an index statring from 0. wraps around if the depth is exceeded",
"inhabit"
=== toExp (inhabit :: Zwirn Int -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> a -> a"
--| "",
"select"
=== toExp (select :: Zwirn Double -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> a -> a"
--| "select a certain layer of a cord using a number between 0 and 1",
"insert"
=== toExp (C.insert :: Zwirn Int -> Zwirn Expression -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> a -> a -> a"
--| "insert into a specific layer of a cord",
"push"
=== toExp (C.push :: Zwirn Expression -> Zwirn Expression -> Zwirn Expression)
<:: "a -> a -> a"
--| "push on top of a cord",
"(&)"
=== toExp (C.concat :: Zwirn Expression -> Zwirn Expression -> Zwirn Expression)
<:: "a -> a -> a"
--| "concat two cords",
"concat"
=== toExp (C.concat :: Zwirn Expression -> Zwirn Expression -> Zwirn Expression)
<:: "a -> a -> a"
--| "concat two cords",
"pop"
=== toExp (C.pop :: Zwirn Expression -> Zwirn Expression)
<:: "a -> a"
--| "remove the top value of a cord",
"remove"
=== toExp (remove :: Zwirn Int -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> a -> a"
--| "remove a specific layer of a cord",
"filter"
=== toExp (C.filter :: Zwirn (Zwirn Expression -> Zwirn Bool) -> Zwirn Expression -> Zwirn Expression)
<:: "(a -> Number) -> a -> a"
--| "filter with a predicate",
"take"
=== toExp (C.take :: Zwirn Int -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> a -> a"
--| "take the first n items of a cord",
"drop"
=== toExp (C.drop :: Zwirn Int -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> a -> a"
--| "drop the first n items of a cord",
"replicate"
=== toExp (C.replicate :: Zwirn Int -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> a -> a"
--| "layer the same item n times",
"superimpose"
=== toExp (superimpose :: Zwirn (Zwirn Expression -> Zwirn Expression) -> Zwirn Expression -> Zwirn Expression)
<:: "(a -> a) -> a -> a"
--| "```superimpose f x = [(f x), x]```",
"ghostWith"
=== toExp (ghostWith :: Zwirn Time -> Zwirn (Zwirn Expression -> Zwirn Expression) -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> (a -> a) -> a -> a"
--| "```ghostWith n f x = [(shift (n |* 1.5) $ f x), (shift (n |* 2.5) $ f x), x]```",
"arp"
=== toExp (arp :: Zwirn Expression -> Zwirn Expression)
<:: "a -> a"
--| "arpeggiate",
"reverse"
=== toExp (C.reverse :: Zwirn Expression -> Zwirn Expression)
<:: "a -> a"
--| "reverse order of cord",
"invert"
=== toExp (C.invert :: Zwirn Expression -> Zwirn Expression)
<:: "Number -> Number"
--| "chord inversion",
"rotate"
=== toExp (C.rotate :: Zwirn Int -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> a -> a"
--| "cord rotation",
"expand"
=== toExp (C.expand :: Zwirn Int -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> Number -> Number"
--| "cord expansion",
"open"
=== toExp (C.open :: Zwirn Expression -> Zwirn Expression)
<:: "Number -> Number"
--| "open cord",
"cat"
=== toExp (cordcat :: Zwirn Expression -> Zwirn Expression)
<:: "a -> a"
--| "```cat [x, y, .. z] == [x y .. z]```",
"timerun"
=== toExp (timerun :: Zwirn Time -> Zwirn Int)
<:: "Number -> Number"
--| "",
"map"
=== toExp (cordmap :: Zwirn (Zwirn Expression -> Zwirn Expression) -> Zwirn Expression -> Zwirn Expression)
<:: "(a -> b) -> a -> b"
--| "```map f [x, y, .. z] == [(f x), (f y), .. (f z)```]",
"layer"
=== toExp (layer :: Zwirn (Zwirn Expression -> Zwirn Expression) -> Zwirn Expression -> Zwirn Expression)
<:: "(a -> b) -> a -> b"
--| "```layer [f, g, .. h] x == [(f x), (g x), .. (h x)```]",
"echoWith"
=== toExp (echoWith :: Zwirn Int -> Zwirn Time -> Zwirn (Zwirn Expression -> Zwirn Expression) -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> Number -> (a -> b) -> a -> b"
--| "",
"followWith"
=== toExp (followWith :: Zwirn Int -> Zwirn Time -> Zwirn (Zwirn Expression -> Zwirn Expression) -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> Number -> (a -> b) -> a -> b"
--| "",
"fold"
=== toExp (fold :: Zwirn (Zwirn Expression -> Zwirn (Zwirn Expression -> Zwirn Expression)) -> Zwirn Expression -> Zwirn Expression)
<:: "(a -> a -> a) -> a -> a"
--| "fold a function over a cord",
"smooth"
=== toExp (interpol :: Zwirn Time -> Zwirn Time)
<:: "Number -> Number"
--| "linear interpolation of items in a cord",
"depth"
=== toExp (depth :: Zwirn Expression -> Zwirn Int)
<:: "a -> Number"
--| "the depth of a cord",
"at"
=== toExp (at :: Zwirn Int -> Zwirn (Zwirn Expression -> Zwirn Expression) -> Zwirn Expression -> Zwirn Expression)
<:: "Number -> (a -> a) -> a -> a"
--| "apply a function to a specific layer of a cord",
"cordFromTo"
=== toExp (enumFromToStack :: Zwirn Double -> Zwirn Double -> Zwirn Double)
<:: "Number -> Number -> Number"
--| "```cordFromTo x y == [x, .. y]```",
"cordFromThenTo"
=== toExp (enumFromThenToStack :: Zwirn Double -> Zwirn Double -> Zwirn Double -> Zwirn Double)
<:: "Number -> Number -> Number -> Number"
--| "```cordFromThenTo x y z == [x, y .. z]```"
]
mapFunctions :: Map.Map Text AnnotatedExpression
mapFunctions =
Map.unions
[ "pN"
=== toExp ((\t -> fmap toExp . singleton t) :: Zwirn Text -> Zwirn Double -> Zwirn Expression)
<:: "Text -> Number -> Map"
--| "number singleton with specific key",
"pI"
=== toExp ((\t -> fmap toExp . singleton t) :: Zwirn Text -> Zwirn Int -> Zwirn Expression)
<:: "Text -> Number -> Map"
--| "integer singleton with specific key",
"pT"
=== toExp ((\t -> fmap toExp . singleton t) :: Zwirn Text -> Zwirn Text -> Zwirn Expression)
<:: "Text -> Text -> Map"
--| "text singleton with specific key",
"(#)"
=== toExp (union :: Zwirn ExpressionMap -> Zwirn ExpressionMap -> Zwirn ExpressionMap)
<:: "Map -> Map -> Map"
--| "union of two maps - structure from the left",
"lookupN"
=== toExp (M.lookup :: Zwirn Text -> Zwirn ExpressionMap -> Zwirn Expression)
<:: "Text -> Map -> Number"
--| "retrieve number at given key or silence if key is missing or it's value not a number",
"lookupT"
=== toExp (M.lookup :: Zwirn Text -> Zwirn ExpressionMap -> Zwirn Expression)
<:: "Text -> Map -> Text"
--| "retrieve text at given key or silence if key is missing or it's value not a text",
"fix"
=== toExp (M.fix :: Zwirn Text -> Zwirn (Zwirn Expression -> Zwirn Expression) -> Zwirn ExpressionMap -> Zwirn ExpressionMap)
<:: "Text -> (a -> a) -> Map -> Map"
--| "apply a function to a specific key",
"loopAt"
=== toExp (loopAt :: Zwirn Time -> Zwirn ExpressionMap -> Zwirn ExpressionMap)
<:: "Number -> Map -> Map"
--| "",
"slice"
=== toExp (slice :: Zwirn Int -> Zwirn Int -> Zwirn ExpressionMap -> Zwirn ExpressionMap)
<:: "Number -> Number -> Map -> Map"
--| "slice a sample into equal btis and index into them",
"juxBy"
=== toExp (juxBy :: Zwirn Expression -> Zwirn (Zwirn ExpressionMap -> Zwirn ExpressionMap) -> Zwirn ExpressionMap -> Zwirn ExpressionMap)
<:: "Number -> (Map -> Map) -> Map -> Map"
--| "thanks yaxu",
"jux"
=== toExp (jux :: Zwirn (Zwirn ExpressionMap -> Zwirn ExpressionMap) -> Zwirn ExpressionMap -> Zwirn ExpressionMap)
<:: "(Map -> Map) -> Map -> Map"
--| "thanks yaxu",
"echo"
=== toExp (echo :: Zwirn Int -> Zwirn Time -> Zwirn Expression -> Zwirn ExpressionMap -> Zwirn ExpressionMap)
<:: "Number -> Number -> Number -> Map -> Map"
--| "",
"chop"
=== toExp (chop :: Zwirn Int -> Zwirn ExpressionMap -> Zwirn ExpressionMap)
<:: "Number -> Map -> Map"
--| "",
"striate"
=== toExp (striate :: Zwirn Int -> Zwirn ExpressionMap -> Zwirn ExpressionMap)
<:: "Number -> Map -> Map"
--| "",
"striateBy"
=== toExp (striateBy :: Zwirn Int -> Zwirn Expression -> Zwirn ExpressionMap -> Zwirn ExpressionMap)
<:: "Number -> Number -> Map -> Map"
--| "",
"param"
=== toExp paramName
<:: "(a -> Map) -> Text"
--| "given a parameter function, gives back the name of the parameter as text"
]
streamFunctions :: Stream -> Map.Map Text AnnotatedExpression
streamFunctions str =
Map.unions
[ "replace"
=== toExp (replace str)
<:: "Id a => a -> Map -> Action"
--| "replace the channel running with given id",
"target"
=== toExp target
<:: "Id a => Text -> a -> Map"
--| "specify a specific target",
"($:)"
=== toExp (replace str)
<:: "Id a => a -> Map -> Action"
--| "replace the channel running with given id",
"replaceAction"
=== toExp (replaceAction str)
<:: "Id a => a -> Action -> Action"
--| "replace the channel running with given id",
"($!)"
=== toExp (replaceAction str)
<:: "Id a => a -> Action -> Action"
--| "replace the channel running with given id",
"replaceBus"
=== toExp (replaceBus str)
<:: "Id a => a -> Number -> Action"
--| "replace the bus running with given id",
"(&:)"
=== toExp (replaceBus str)
<:: "Id a => a -> Number -> Action"
--| "replace the bus running with given id",
"fx"
=== toExp (fx str)
<:: "Id a => a -> (Map -> Map) -> Action"
--| "apply the function to channel with given id",
"(#!)"
=== toExp (fx str)
<:: "Id a => a -> (Map -> Map) -> Action"
--| "replace the bus running with given id",
"all"
=== toExp allID
<:: "Text"
--| "special identifier to apply effects to all channels",
"none"
=== toExp noneID
<:: "Text"
--| "special identifier to remove effects from all channels",
"tempo"
=== toExp tempo
<:: "Number"
--| "current tempo in bpm",
"bpc"
=== toExp bpc
<:: "Number"
--| "current beats per cycle",
"hush"
=== toExp (hush str)
<:: "Action"
--| "hush all channels",
"once"
=== toExp (once str)
<:: "Map -> Action"
--| "play one cycle of the given zwirn",
"tonce"
=== toExp (tonce str)
<:: "Text -> Map -> Action"
--| "play one cycle of the given zwirn on the given target",
"mute"
=== toExp (mute str)
<:: "Id a => a -> Action"
--| "mute channel with given id",
"unmute"
=== toExp (unmute str)
<:: "Id a => a -> Action"
--| "unmute channel with given id",
"toggle"
=== toExp (toggle str)
<:: "Id a => a -> Action"
--| "toggle channel with given id",
"solo"
=== toExp (solo str)
<:: "Id a => a -> Action"
--| "solo channel with given id",
"unsolo"
=== toExp (unsolo str)
<:: "Id a => a -> Action"
--| "unsolo channel with given id",
"togglesolo"
=== toExp (togglesolo str)
<:: "Id a => a -> Action"
--| "toggle solo channel with given id",
"bpm"
=== toExp (bpm str)
<:: "Number -> Action"
--| "set the current bpm (beats per minute)",
"cps"
=== toExp (cps str)
<:: "Number -> Action"
--| "set the current cps (cycles per second)",
"resetcycles"
=== toExp (resetcycles str)
<:: "Action"
--| "resets the cycle count to 0",
"setcycle"
=== toExp (setcycle str)
<:: "Number -> Action"
--| "set the current cycle to specific point in time",
"disablelink"
=== toExp (disablelink str)
<:: "Action"
--| "disable ableton link",
"enablelink"
=== toExp (enablelink str)
<:: "Action"
--| "enable ableton link",
"in"
=== toExp (execIn' str)
<:: "Number -> Action -> Action"
--| "start an action in a given amount of seconds",
"inMod"
=== toExp (execMod str)
<:: "Number -> Action -> Action"
--| "start an action in a given amount of seconds",
"transitionmap"
=== toExp (transition str)
<:: "Id a => a -> (Number -> Map -> Map) -> Action"
--| "",
"transition"
=== toExp (transition' str)
<:: "Id a => a -> Number -> b -> b -> (Map -> b -> Map) -> Action"
--| ""
]