Closed yaxu closed 2 years ago
Functions:
Desirable syntax:
jux (fast 2 . rev) ...
Potentially useful syntax:
\x -> fast 2 $ rev x
This doesn't work, but only because id
is missing from tidal-parse:
spread ($) [id, rev, fast 2]
I could add it to genericTransformations
, but that isn't generic enough, as id is a -> a
, not Pattern a -> Pattern a
. So @dktr0 the question is, how low do we want to go?
I would just add it to genericTransformations for now, since I don't think there are currently any other places (in tidal-parse) where a -> a would be used. And later rework.
@dktr0 Ok, I suppose there are not many non-patterned parameters left, so a -> a
is pretty much out of scope anyway
One liner to get a list of functions currently supported by tidal-parse:
perl -e 'undef $/; $all = <>; while ($all =~ /fromTidal\s*"([^"]+)"/og) {print "$1\n"}' Parse.hs |sort > current.txt
Hacky one liner to get a list of functions in a module with type:
echo ":browse Sound.Tidal.UI" | ghci |perl -e 'undef $/; $_ = <>; s/^GHC.*?\n//g; s/Prelude> //g; s/\n +/ /go; s/(?:\n|^)(\()Sound\.Tidal\.\w+?\./\n$1/sg; s/\nLeaving.*//; s/^\n//; print'|egrep -v '^_' > ui.txt
Another hack to make a list of missing functions:
perl -e '@ui = `cat ui.txt`; chomp @ui; @current = `cat current.txt`; chomp @current; foreach $type (@ui) {$type =~ s/Sound\.Tidal\.\w+\.//g; $type =~ /^(\S+) (.*)/; $func = $1; $type = $2; if (not (grep {$func eq $_} @current)) {print "- [ ] **$func** `$type`\n"}}'
Here's a version of the above (now deleted) lists combined, with most internal functions removed, and sorted by type, not name
:: (Applicative a, Floating b) => a b -> a b -> a b
:: (Applicative a, Fractional b) => a b -> a b -> a b
:: (Applicative a, Num b) => a b -> a b -> a b
:: (Applicative a, Num b) => a b -> a b -> a b
:: (Applicative a, Num b) => a b -> a b -> a b
:: (Applicative a, Real b) => a b -> a b -> a b
:: (Applicative a, Unionable b) => a b -> a b -> a b
:: (Applicative a, Unionable b) => a b -> a b -> a b
:: (ControlPattern -> ControlPattern) -> (ControlPattern -> ControlPattern) -> ControlPattern -> ControlPattern -> ControlPattern
:: (ControlPattern -> ControlPattern) -> ControlPattern -> ControlPattern -> ControlPattern
:: (ControlPattern -> ControlPattern) -> ControlPattern -> ControlPattern -> ControlPattern
:: (ControlPattern -> Pattern ControlMap) -> Pattern (Data.Map.Internal.Map String (Value, Value)) -> ControlPattern -> Pattern ControlMap
:: (ControlPattern -> Pattern ControlMap) -> Pattern (Data.Map.Internal.Map String (Value, Value)) -> ControlPattern -> Pattern ControlMap
:: (ControlPattern -> Pattern a) -> (ControlPattern -> Pattern a) -> Pattern (Data.Map.Internal.Map String (Value, Value)) -> ControlPattern -> Pattern a
:: (Enum a, Num a) => Pattern a -> Pattern a
:: (Enumerable a, Parseable a) => String -> Pattern a
:: (Functor f, Floating b) => b -> b -> f b -> f b
:: (Functor f, RealFrac b) => b -> f b -> f b
:: (Int -> Bool) -> (Pattern a -> Pattern a) -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
:: (Int -> Bool) -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
:: (Pattern ControlMap -> Pattern ControlMap) -> Pattern ControlMap -> Pattern ControlMap
:: (Pattern ControlMap -> Pattern ControlMap) -> Pattern ControlMap -> Pattern ControlMap
:: (Pattern a -> Pattern a) -> Pattern a -> Pattern a
:: (Time -> Bool) -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
:: (Time -> a) -> Pattern a
:: (Time, Time) -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
:: (Time, Time) -> Pattern a -> Pattern a
:: ([EventF (ArcF Time) a] -> [EventF (ArcF Time) b]) -> Pattern a -> Pattern b
:: (a -> Value -> Bool) -> (ControlPattern -> Pattern b) -> (ControlPattern -> Pattern b) -> Pattern (Data.Map.Internal.Map String a) -> Pattern (Data.Map.Internal.Map String Value) -> Pattern b
:: (t -> t1 -> Pattern b) -> [t] -> t1 -> Pattern b
:: (t -> t1 -> Pattern b) -> [t] -> t1 -> Pattern b
:: Applicative a => a String -> a String -> a String
:: Applicative f => f String -> f Int -> f String
:: Arc -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
:: Arc -> Pattern a -> Pattern a
:: Bool -> String -> Pattern Bool
:: ControlPattern -> ControlPattern -> ControlPattern
:: Double -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
:: Double -> String -> Pattern Double
:: Eq a => [(a, b)] -> Pattern a -> Pattern b
:: Floating a => Pattern a -> Pattern a -> Pattern a
:: Floating a => Pattern a -> Pattern a -> Pattern a
:: Fractional a => Pattern a -> Pattern a -> Pattern a
:: Fractional a => Pattern a -> Pattern a -> Pattern a
:: Fractional a => Pattern a -> Pattern a
:: Fractional a => Pattern a -> Pattern a
:: Fractional a => Pattern a -> Pattern a
:: Functor f => f Bool -> f Bool
:: Int -> (Pattern a -> Pattern a -> Pattern a) -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
:: Int -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
:: Int -> (Pattern b -> Pattern b) -> Pattern b -> Pattern b
:: Int -> Pattern Int -> ControlPattern -> Pattern (Data.Map.Internal.Map String Value)
:: Int -> Pattern Int -> Pattern a -> Pattern a
:: Int -> Pattern Int
:: Int -> Pattern Int
:: Int -> Pattern String -> String
:: Int -> Pattern [Arc]
:: Int -> Pattern a -> Pattern a -> Pattern a
:: Int -> Pattern a -> Pattern a
:: Int -> String -> Pattern Int
:: Int -> String -> String -> String
:: Int -> [Pattern Time] -> ControlPattern -> Pattern ControlMap
:: Int -> [[Double]] -> Int -> Time -> [Int]
:: Integral a => a -> (Pattern b -> Pattern b) -> Pattern b -> Pattern b
:: Integral a => a -> (Pattern b -> Pattern b) -> Pattern b -> Pattern b
:: Integral i => i -> Time -> Pattern a -> Pattern a
:: Monad m => (a -> b -> m c) -> m a -> b -> m c
:: Num a => Int -> [a] -> Pattern Int -> Pattern a
:: Num a => Pattern Time -> Pattern a -> Pattern a -> Pattern a
:: Num a => Pattern a -> Pattern a -> Pattern a
:: Num a => Pattern a -> Pattern a -> Pattern a
:: Num a => Pattern a -> Pattern a -> Pattern a
:: Num a => Pattern a -> Pattern a -> Pattern a
:: Num a => Pattern a -> Pattern a -> Pattern a
:: Num a => Pattern a -> Pattern a -> Pattern a
:: Num a => [a] -> Pattern Int -> Pattern a
:: Num b => Int -> String -> String -> [b]
:: Ord a => Pattern Int -> Pattern a -> Pattern a
:: Pattern (a -> b) -> Pattern a -> Pattern b
:: Pattern (a -> b) -> Pattern a -> Pattern b
:: Pattern Bool -> Pattern a -> Pattern a -> Pattern a
:: Pattern ControlMap -> Pattern ControlMap
:: Pattern ControlPattern -> ControlPattern
:: Pattern Double -> (Pattern ControlMap -> Pattern ControlMap) -> Pattern ControlMap -> Pattern ControlMap
:: Pattern Double -> Pattern Double -> Pattern Double
:: Pattern Double -> Pattern Double
:: Pattern Double -> Pattern Double
:: Pattern Double -> [(a, Double)] -> Pattern a
:: Pattern Double -> [Pattern a -> Pattern a] -> Pattern a -> Pattern a
:: Pattern Double -> [Pattern a] -> Pattern a
:: Pattern Double -> [a] -> Pattern a
:: Pattern Double
:: Pattern Double
:: Pattern Double
:: Pattern Double
:: Pattern Double
:: Pattern Double
(and friends):: Pattern Int -> ControlPattern -> ControlPattern
:: Pattern Int -> ControlPattern -> ControlPattern
:: Pattern Int -> ControlPattern -> ControlPattern
:: Pattern Int -> Pattern Double -> ControlPattern -> ControlPattern
:: Pattern Int -> Pattern Int -> ControlPattern -> ControlPattern
:: Pattern Int -> Pattern Int -> Pattern Int -> Pattern Bool -> Pattern Bool
:: Pattern Int -> Pattern Int -> Pattern Int -> Pattern a -> Pattern a
:: Pattern Int -> Pattern Int -> Pattern Int -> Pattern a -> Pattern a
:: Pattern Int -> Pattern Int -> [[Double]] -> Pattern Int
:: Pattern Int -> Pattern Time -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
:: Pattern Int -> Pattern Time -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
:: Pattern Int -> Pattern a -> Pattern a
:: Pattern Int -> [Pattern Time] -> ControlPattern -> Pattern ControlMap
:: Pattern Int -> [Pattern a -> Pattern a] -> Pattern a -> Pattern a
:: Pattern Int -> [Pattern a] -> Pattern a
:: Pattern String -> Pattern String -> Pattern String
:: Pattern String -> Pattern String -> Pattern String
:: Pattern String -> Pattern a -> Pattern a
:: Pattern Time -> (Pattern a1 -> Pattern a) -> Pattern a1 -> Pattern a
:: Pattern Time -> (Pattern a1 -> Pattern a) -> Pattern a1 -> Pattern a
:: Pattern Time -> ControlPattern -> ControlPattern
:: Pattern Time -> Pattern a -> Pattern a
:: Pattern Time -> Pattern a -> Pattern a
:: Pattern Time -> Pattern a -> Pattern a
:: Pattern Time -> Pattern a -> Pattern a
:: Pattern [a] -> Pattern a
:: Pattern a -> Pattern a -> Pattern a
:: Pattern a -> Pattern a
:: Pattern a -> Pattern a
:: Pattern a -> Pattern a
:: Rational -> String -> Pattern Rational
:: Real a => Pattern a -> Pattern a -> Pattern a
:: Real a => Pattern a -> Pattern a -> Pattern a
:: Real b => b -> Pattern b -> Pattern c -> Pattern c
:: RealFrac b => Int -> [a] -> Pattern b -> Pattern a
:: Show a => a -> Pattern b -> Pattern b
:: Show a => a -> Pattern b -> Pattern b
:: Show a => a -> Pattern b -> Pattern b
:: Show a => a -> Pattern b -> Pattern b
:: String -> Int -> String
:: String -> Pattern Bool
:: String -> Pattern Bool
:: String -> Pattern Double
:: String -> Pattern Double
:: String -> Pattern Int
:: String -> Pattern Int
:: String -> Pattern Rational
:: String -> Pattern Rational
:: String -> Pattern String
:: String -> Pattern String
:: String -> Pattern Time
:: String -> Pattern Time
:: String -> String -> Pattern String
:: String -> String -> Pattern String
:: String -> [(Char, String)]
:: String -> [(String, String)]
:: Time -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
:: Time -> ControlPattern -> [ControlPattern] -> ControlPattern
:: Time -> Pattern ControlMap -> Pattern ControlMap
:: Time -> Pattern String -> [(String, Pattern a)] -> [(String, Pattern a -> Pattern a)] -> Pattern a
:: Time -> Pattern a -> Pattern a -> Pattern a
:: Time -> Pattern a -> Pattern a
:: Time -> Pattern a -> Pattern a
:: Time -> Pattern a -> Pattern a
:: Time -> Pattern a -> Pattern a
:: Time -> Pattern a -> Pattern a
:: Time -> Pattern a -> Pattern a
:: Time -> Pattern a -> [Pattern a -> Pattern a] -> Pattern a
:: Time -> Pattern a -> [Pattern a -> Pattern a] -> Pattern a
:: Time -> String -> Pattern Time
:: Time -> Time -> Pattern a -> Pattern a
:: Time -> Time -> Pattern a -> Pattern a
:: Unionable a => Pattern a -> Pattern a -> Pattern a
:: Unionable a => Pattern a -> Pattern a -> Pattern a
:: Unionable a => Pattern a -> Pattern a -> Pattern a
:: Unionable a => Pattern a -> Pattern a -> Pattern a
:: Unionable a => Pattern a -> [Pattern a] -> Pattern a
:: Unionable b => Pattern b -> Pattern b -> Pattern b
:: [(String, Pattern a)] -> Pattern String -> Pattern a
:: [(String, String)] -> Pattern String
:: [(Time, Pattern a)] -> Pattern a
:: [(Time, Time, Pattern a)] -> Pattern a
:: [(Time, Time, Pattern a)] -> Pattern a
:: [(a, Double)] -> Pattern a
:: [Arc] -> Arc
:: [Maybe a] -> Pattern a
:: [Pattern a] -> Pattern a
:: [Pattern a] -> Pattern a
:: [String] -> String -> Pattern String
:: [a -> Pattern b] -> a -> Pattern b
:: [a -> Pattern b] -> a -> Pattern b
:: [a] -> Pattern a
:: [a] -> Pattern a
:: [t -> Pattern ControlMap] -> t -> Pattern ControlMap
:: [t -> Pattern ControlMap] -> t -> Pattern ControlMap
Made with
perl -e '@foo = `cat list.txt`; chomp @foo; @bar = map {$_ =~ /(::.*)/; [$_,$1]} @foo; @qux = sort {$a->[1] cmp $b->[1] || $a->[0] cmp $b->[0]} @bar; @final = map {$_->[0]} @qux; foreach $line (@qux) {print "$line->[0]\n"}'
Well that's post-modern (using Perl to analyze Haskell projects)!
Not to be nitpicky but it does seem to identify some things as missing that are not missing, especially operators like |/|
It's entirely possible that my crufty regex approach wasn't 100% accurate!
Might just be something to do with difference between <| and (<|)?
Yes probably, I've ticked them off for now
Now I understand what the tick boxes are for! :)
This is all super useful - will be easy to fill all this in in the next little while
Good! Out of interest, are you able to tick the boxes by clicking on them in my comment?
I just checked the last one spuriously - is it checked for you? I guess I kind of doubt it...
(juxcut')
Yes that worked, I unchecked it again
I've been doing a couple more of these (pr soon), but can you summarise the reason for not generating all this straight from the types @dktr0 ? Is there some pragmatism about how the currying works?
Just haven't got that far with the TH and prefer something that works right now and which gives workshop experiences with Tidal to hundreds of students at a time over abstraction and automation for the sake of abstraction and automation...
I know I can debug and maintain this. I do not know that for the fully automatic one.
Still, I think the automatic thing will probably be the right step eventually...
Basically I think that's a big and complicated refactor, with uncertain ultimate costs, and not a huge payoff in terms of what it makes available to the audiences I care about. If someone else is able to pull it off, great I guess (although I worry a bit about not being able to follow/debug it from that point on...).
I meant auto-generating the code (e.g. using more shonky perl code) rather than doing funky stuff with TH.
If it's doable, I'd be happy to do the job! Just need to understand what's going on and what the gotchas are..
Having problems working out how to add the Ord
constraint in rot :: Ord a => Pattern Int -> Pattern a -> Pattern a
In this case I think I can just remove that constraint from the function itself though..
Hm I can only get it to rot :: Eq a => Pattern Int -> Pattern a -> Pattern a
, as some comparison of values has to happen.
These kind of questions are part of why I am reluctant to automate further than already - it sounds nice but there are lots of little wrinkles that IMHO are easier to think through at a lower level of abstraction. Obviously your mileage may vary. Not super in favour of doing things in Perl as it will further limit my ability to continue contributing to this work (I don't have time and energy to spend on Perl, sorry).
I'll add rot now and add it to the pull request already in the queue for clip and vol.
I do think the higher abstraction TH route is viable - just takes some careful thought and very careful documentation...
Ok rot is there in the pull request with vol and clip now.
also added the fastCat/slowCat synonyms
Basically adding something like rot that has a type (ie. with the constraints) we don't already have is about adding a new instance or definition for that type, then taking off the first argument and repeating the process (adding new instances or definitions as appropriate) until you get to the * instances, where you make sure the new pathway is reflected in every one of them that is possible.
Can I propose that we start conceptual work that lays the groundwork for the more-abstract-TH route without (yet) doing away with the current approach? It will be more robust and hopefully we will both be able to follow and continue to contribute to the result.
Thanks for the rot
!
I don't intend to make Perl a dev dependency for anything.. Just trying to work out whether we can just generate these definitions as a one-off. It seems that we're just describing a type in code, which seems to be a data munging rather than manual task.. But I think I'm missing something, and so was asking what that missing thing was.
I've gotten as far as making some TH to take a list of Tidal functions and get the info about their type as a Map from their names to that info. Here's it in action:
*Sound.Tidal.Parse> $(reifyTidals ["s","n"] >>= (stringE . show))
"fromList [(\"n\",VarI Sound.Tidal.Params.n (AppT (AppT ArrowT (AppT (ConT Sound.Tidal.Pattern.Pattern) (ConT GHC.Types.Double))) (ConT Sound.Tidal.Pattern.ControlPattern)) Nothing),(\"s\",VarI Sound.Tidal.Params.s (AppT (AppT ArrowT (AppT (ConT Sound.Tidal.Pattern.Pattern) (ConT GHC.Base.String))) (ConT Sound.Tidal.Pattern.ControlPattern)) Nothing)]"
Have pushed that to a branch called th-parse on my fork for now
Is this issue still useful @dktr0 ?
@yaxu Nah, not really, I'll close it!
An issue for collecting requests for missing functions, operators and syntax for tidal-parse (formerly known as minitidal)