Closed yaxu closed 6 years ago
In the currently released tidal the whole
and the part
timespans are always the same as the query timespan. This is usually fine as you don't normally take structure from continuous patterns. Now the default might be to take structure from both sides, this will become more of a problem.
One option could be to wrap the 'whole' into a Maybe, to represent continuous events which don't have a start or end:
data Pattern = Pattern {query :: (Span -> [((Maybe Span, Span), a)])}
Looks OK so far, haven't actually tried anything with continuous patterns yet though!
Hm I think this solution isn't working out. You really need to know whether a pattern is discrete or continuous not before you query it, so you know whether you're looking to match a range or a point.. So probably back to having different type constructors..
Instead I'm trying putting a flag on Pattern
to indicate whether it should be treated as continuous or discrete. I'm using Analog
and Digital
because they're shorter..
type Time = Rational
type Arc = (Time, Time)
type Part = (Arc, Arc)
type Event a = (Part, a)
type Query a = (Arc -> [Event a])
type Nature = Analog | Digital
data Pattern a = Pattern {nature :: Nature, query :: Query a}
<*>
then looks something like this (untested):
pf <*> px | isDigital pf && isDigital px = Pattern Digital q
where q arc = catMaybes $ concat $ map match $ query pf arc
where
match ((fWhole, fPart), f) =
map
(\((xWhole, xPart),x) ->
do part' <- subArc fPart xPart
whole' <- subArc xWhole' fWhole
return ((whole', part'), f x)
)
(query px fPart)
| isDigital pf && isAnalog px = Pattern Digital q
where q arc = concatMap match $ query pf arc
where
match ((fWhole, fPart), f) =
map
(\(_ ,x) -> ((fWhole, fPart), f x))
(query px (fst fPart, fst fPart)
| isAnalog pf && isDigital px = Pattern Digital q
where q arc = concatMap match $ query px arc
where
match ((xWhole, xPart), x) =
map
(\(_ ,f) -> ((xWhole, xPart), f x))
(query pf (fst xPart, fst xPart)
| otherwise = Pattern Analog q
where q arc = concatMap match $ query pf arc
where
match (_, f) =
map
(\(_ ,x) -> (arc, f x))
(query px arc)
I've got this approach passing tests now..
I'm thinking that
sig
and thereforesine
etc should always return an event with a 'whole' that starts at something like-1
, i.e signals should have no onsets on the timeline. Thensaw + "1 2"
(or"1 2" + saw
) would be the same as"1 2.5"
. However, then I'm not sure what the 'end' of the whole should be..