Hi! I've posted some while ago a link to soundcloud of my band. We use the haskell based music. We've made a good quality vidoe, maybe you'll find it interesting https:// The cello synth is made with Haskell. Also the drone and high glitchy drums are made with Haskell too. With my lib csound-expression. Everything is put together and controlled with Csound. The audio flows frmo Csound by JACK to Bitwig Studio where it;s mixed and recorded. The audio was recorded live. Though it was mixed and mastered in studio environment. It's hard to record the music like this instrument by instrument since all parts are improvised. And it's slightly different each time we play it. Thanks for watching! Anton
Posts in Haskell Art
mark.santolucito 1st CFP : Functional Art, Music, Modelling, and Design (FARM) 2017 @ ICFP Posted at 2:34pm, Mar 28
5th ACM SIGPLAN International Workshop on Functional Art, Music, Modelling and Design Oxford, UK, September, 9th 2017 Key Dates: Submission deadline June 1, 2017 Author Notification July 1, 2017 Camera Ready July 13, 2017 Call for Papers and Demos: The ACM SIGPLAN International Workshop on Functional Art, Music, Modelling and Design (FARM) gathers together people who are harnessing functional techniques in the pursuit of creativity and expression. It is co-located with ICFP 2017, the 22nd ACM SIGPLAN International Conference on Functional Programming. Functional Programming has emerged as a mainstream software development paradigm, and its artistic and creative use is booming. A growing number of software toolkits, frameworks and environments for art, music and design now employ functional programming languages and techniques. FARM is a forum for exploration and critical evaluation of these developments, for example to consider potential benefits of greater consistency, tersity, and closer mapping to a problem domain. FARM encourages submissions from across art, craft and design, including textiles, visual art, music, 3D sculpture, animation, GUIs, video games, 3D printing and architectural models, choreography, poetry, and even VLSI layouts, GPU configurations, or mechanical engineering designs. Theoretical foundations, language design, implementation issues, and applications in industry or the arts are all within the scope of the workshop. The language used need not be purely functional (“mostly functional” is fine), and may be manifested as a domain specific language or tool. Moreover, submissions focusing on questions or issues about the use of functional programming are within the scope. FARM 2017 website : http://functional-art.org/2017/ Submissions We welcome submissions from academic, professional, and independent programmers and artists. Submissions are invited in three categories: 1) Original papers We solicit original papers in the following categories: - Original research - Overview / state of the art - Technology tutorial All submissions must propose an original contribution to the FARM theme. FARM is an interdisciplinary conference, so a wide range of approaches are encouraged. An original paper should have 5 to 12 pages, be in portable document format (PDF), using the ACM SIGPLAN style guidelines and use the ACM SIGPLAN template. [ http://www.sigplan.org/Resources/Author/ ] Accepted papers will be published in the ACM Digital Library as part of the FARM 2017 proceedings. See http://authors.acm.org/main.cfm for information on the options available to authors. Authors are encouraged to submit auxiliary material for publication along with their paper (source code, data, videos, images, etc.); authors retain all rights to the auxiliary material. 2) Demo proposals Demo proposals should describe a demonstration to be given at the FARM workshop and its context, connecting it with the themes of FARM. A demo could be in the form of a short (10-20 minute) tutorial, presentation of work-in-progress, an exhibition of some work, or even a performance. Demo proposals should be in plain text, HTML or Markdown format, and not exceed 2000 words. A demo proposal should be clearly marked as such, by prepending Demo Proposal: to the title. Demo proposals will be published on the FARM website. A summary of the demo performances will also be published as part of the conference proceedings, to be prepared by the program chair. 3) Calls for collaboration Calls for collaboration should describe a need for technology or expertise related to the FARM theme. Examples may include but are not restricted to: - art projects in need of realization - existing software or hardware that may benefit from functional programming - unfinished projects in need of inspiration Calls for collaboration should be in plain text, HTML or Markdown format, and not exceed 5000 words. A call for collaboration should be clearly marked as such, by prepending Call for Collaboration: to the title. Calls for collaboration will be published on the FARM website. Submission is via EasyChair https://easychair.org/conferences/?conf=farm2017 Authors take note The official publication date is the date the proceedings are made available in the ACM Digital Library. This date may be up to two weeks prior to the first day of your conference. The official publication date affects the deadline for any patent filings related to published work. Questions If you have any questions about what type of contributions that might be suitable, or anything else regarding submission or the workshop itself, please contact the organisers at: <email obscured> All presentations at FARM 2017 will be recorded. Permission to publish the resulting video (in all probability on YouTube, along with the videos of ICFP itself and the other ICFP-colocated events) will be requested on-site.
fa-ml Announcement: package 'audacity' for exchange data between Haskell and Audacity Posted at 12:35pm, Mar 25
On Sat, Mar 25, 2017 at 09:12:37AM +0100, Henning Thielemann wrote: > > I released the 'audacity' package: > http://hackage.haskell.org/package/audacity > Sweet, I have something I long wished to automatise and this for sure will come handy!
haskell-art Announcement: package 'audacity' for exchange data between Haskell and Audacity Posted at 8:13am, Mar 25
I released the 'audacity' package: http://hackage.haskell.org/package/audacity The package provides functions for interchange with the Audacity sound signal editor. Currently we support import and export of label tracks, export of Audacity projects and limited import of tracks from Audacity projects. We provide some examples that are useful on its own: sox-concat: Concatenate a sequence of sound files with matching sampling rates and numbers of channels using SoX and generate an Audacity label track file that shows the origins of the parts. audacity-concat: Create an Audacity project file containing a virtual concatenation of the input sound files and a label track showing the origins of the sound files. audacity-combine: Put several audio and label files into tracks of a new Audacity project. Opening one or even multiple such projects is much easier than loading individual tracks into Audacity. I would have prefered to complete the import of Audacity projects first, but since I did not manage it for a year now, I decided to release the package anyway. It is already useful in its current state.
Hi! It's been quite a while since I've posted haskell tracks in the list. Here is my new composition made with brand new version of my haskell library. https://soundcloud.com/anton-kho/river-spirits The track is called River Spirits. It's a binaural drone. It features lots of simple harmonics each of them is multiplied by random spline. And each ear has it's own set of random harmonics. Thus we can get thick sound out of very simple primitives.
Dear list, I’d like to Announce the release of the new version of my Haskell computer music framework. It’s quite a big release. Lot’s of cool new features! *The 5.2 is out. Virtual pedalboards, arrays, new OSC, full support for mono synthesizers, patch skins, all GEN-routines are implemented* *New features:* - *Complete support for monophonic synthesizers*: - The argument of mono synth was updated. Previously it was a pair of amplitude and frequency signals. But this representation doesn’t captures the notion of note retrigger. We can not create the mono-synt with sharp attacks. Now this is fixed. We can use adsr140 or adsrMonoSynt functions to create mono synths with fixed attacks - monoSco - for playing scores with mono-synths - monoSched - for playing event streams with mono synt - atSco and atSched now work for mono synth too - *The patch can change the skin*. The Patch type has changed. Know it supports the change in common parameters. Right now the ccommon parameters include only Low-pass filter type. But this can be extended in future releases. The idea is that we can parametrize the patch with some common arguments so that use can tweak them without revriting the algorithm. The low-pass filter is a vital tool that defines the character of the synthesizer. With recent addition of several modern filter emulators (like Korg (korg_lp), or acid filter diode) it’s good to be able to quickly switch the filters. We can do it for patches with function setFilter :: ResonFilter -> Patch a -> Patch a - *Family of standard effects was added* (see module Csound.Air.Fx.FxBox and the guide <https://github.com/spell-music/csound-expression/blob/master/tutorial/chapters/FxFamily.md> ). The effects are kindly provided by Iain McCurdy (recoded from his original implementation in Csound). The effects have catchy names and are defined on wide variety of types. Let’s briefly discuss the naming conventions: - adele - analog delay - pongy - ping pong delay - tort - distortion - flan - flanger - fowler - Envelope follower - phasy - phaser - crusher - bit-crusher - chory - stereo chorus - tremy - tremolo - pany - panning - revsy - reverse playback Also there are set of presets that imply the notion of add a bit of effect or add a lot of effect. They are suffixed with number from 1 to 5. Like flan1 or tort3. Also if the effect support the tone knob (center frequency of LP filter) ter are suffixes b for bright color and m for muted color. For example tort2m or adele2b. The effects are just functions from signals to signals: dac $ hall 0.2 $ adele2 0.5 0.25 $ flan2 $ tort1m $ asigs - *UI widgets for standard effects*. Alongside with effects there are functions to create widgets (UI-controls). They have the same naming convention only the prefix ui is added. For example: uiTort, uiAdele or uiHall. Also there are predefined presets like uiFlan2 or uiPhasy3. With presets we put the box in the initial state corresponding to the given preset. But lately we can change it with UI-controls. With this feature paired with functions fxHor, fxVer and fxGrid we can easily design our virtual pedalboards. It can be used like this: > let pedals = fxGrid 2 [uiFlan1, uiTort1, uiAdele2m 0.5 0.3, uiHall 0.25] > dac $ fxApply pedals $ (sawSeq [1, 0.5, 0.25] 2) * sqr 220 - *Complete list of GEN routines*. This release adds GEN: * 25 bpExps -- Construct functions from segments of exponential curves in breakpoint fashion., * 27 bpLins -- Construct functions from segments of straight lines in breakpoint fashion. * wave waveletTab -- Generates a compactly supported wavelet function. * farey fareyTab -- Fills a table with the Farey Sequence Fn of the integer n. * sone soneTab -- Generate a table with values of the sone function. * exp expTab -- rescaleExpTab Generate a table with values on the exp function. * tanh tanhTab -- rescaleTanhTab Generate a table with values on the tanh function. * 52 readMultichannel -- Creates an interleaved multichannel table from the specified source tables, in the format expected by the ftconv opcode. * 41 randDist -- Generates a random list of numerical pairs. * 42 rangeDist Generates a random distribution of discrete ranges of values. * 40 tabDist -- Generates a random distribution using a distribution histogram. * 43 readPvocex -- Loads a PVOCEX file containing a PV analysis. * 28 readTrajectoryFile -- Reads a text file which contains a time-tagged trajectory. * 24 readNumTab -- Reads numeric values from another allocated function-table and rescales them. * 21 dist, uniDist, linDist, triDist, expDist, biexpDist, gaussDist, cauchyDist, pcauchyDist, betaDist, weibullDist, poissonDist
-- Generates tables of different random distributions. * 18 tabseg -- Writes composite waveforms made up of pre-existing waveforms. * 31 mixOnTab -- Mixes any waveform specified in an existing table. * 32 mixTabs -- Mixes any waveform, resampled with either FFT or linear interpolation. * 30 tabHarmonics -- Generates harmonic partials by analyzing an existing table. See the Csound docs <http://www.csounds.com/manualOLPC/ScoreGenRef.html> for details of what table they produce. Also the signatures for windows creating tabs was updated. It became more specific. - *Global arguments* defined with *Macros*. We can create a Csound .csd file in our program and after that we can run it on anything which has Csound installed. It’s desirable to be able to tweak some parameters after rendering or to have some global config arguments. In Csound we can do it with macroses. We can use macros name in the code adn then we can change the value of the macros with command line flag --omacro:Name=Value. From now on it’s possible to do it with Haskell too. There are functions: readMacrosDouble :: String -> Double -> D readMacrosInt :: String -> Int -> D readMacrosString :: String -> String -> Str The first argument is a macro name and the second one is the default value which is used if no value is set in the flags. - The useful function to *trigger an table based envelope*. It comes in two flavors. One is driven with event stream and another with just a signal. It’s on when signal is non zero. trigTab :: Tab -> Sig -> Sig -> Sig trigTab tab duration triggerSignal type Tick = Evt Unit trigTabEvt :: Tab -> Sig -> Tick -> Sig trigTabEvt tab duration triggerSignal - *New functions for UI widgets*. - We can change the relative size of the window. If the widget is too large or too small we can rescale it with functions: type ScaleFactor = (Double, Double) resizeGui :: ScaleFactor -> Gui -> Gui resizeSource :: ScaleFactor -> Source a -> Source a They change the default minimal sizes for all widgets that are contained within the given widget. - Grid layout. We are familiar with functions ver and hor. With them we can place the widgets vertically or horizontally. But now it’s also possible to place the widgets on the grid: grid :: Int -> [Gui] -> Gui The first argument specifies the number of elements in each row. There are handy grid functions for combining source-widgets: gridLifts :: Int -> ([a] -> b) -> [Source a] -> Source b It applies a list based function to a list of value producer widgets and places all widgets on the grid. The first argument is the same as with grid. - UI default sizes are a bit smaller now. - It compiles on *GHC-7.8* again - New function whileRef for imperative while loops. whileRef :: Tuple st => st -> (st -> SE BoolSig) -> (st -> SE st) -> SE () whileRef initState condition body It’s used in this way. It stores the initial state in the reference (local variable) and the it starts to implement the body while the predicate returns true. Notice that the body is also updates the state. - *New functions for OSC* that make it easy to read OSC messages that are interpreted like signals. For example we have an OSC-routine for volume control. When message happens we update the value. It would be good to be able to just read the signal: listenOscVal :: (Tuple a, OscVal a) => OscRef -> String -> a -> SE a listenOscVal oscRef address initValue There are two useful aliases for this function. They read signals and pairs of signals: listenOscSig :: OscRef -> String -> Sig -> SE Sig listenOscSig2 :: OscRef -> String -> Sig2 -> SE Sig2 - *Adds loopers that preserve attacks when rescaling by tempo*. They are based on temposcal Csound algorithm. The previous loopers were based on the mincer algorithm. It uses FFT under the hood which can smooth out the sharp attacks. It’s undesirable for percussive loops. The temposcal adds the feature of preserving attacks. See the functions: -- | reads stereo files with scaling scaleWav :: Fidelity -> TempoSig -> PitchSig -> String -> Sig2 -- | reads mono files with scaling scaleWav1 :: Fidelity -> TempoSig -> PitchSig -> String -> Sig Also there are presets for scaling the drums or harmonic instruments (they set the appropriate fidelity): scaleDrum, scaleHarm :: TempoSig -> PitchSig -> String -> Sig2 The fidelity is the degree of the size of FFT window. The formula for window size: 2 ** (fidelity + 11). Also the corresponding functions are added for csound-sampler. wavScale :: Fidelity -> TempoSig -> PitchSig -> String -> Sam wavScale1 :: Fidelity -> TempoSig -> PitchSig -> String -> Sam drumScale, harmScale :: TempoSig -> PitchSig -> String -> Sam - The type signatures for *echo and pingPong where simplified*. Now they don’t use side effects and look like pure functions: echo :: MaxDelayTime -> Feedback -> Sig -> Sig pingPong :: DelayTime -> Feedback -> Balance -> Sig2 -> Sig2 - Type signatures for functions *randSkip and freqOf where generalized*. Now they use signals for probabilities instead of constant numbers. So we can change the probability of skip of the event during performance. - *New monophonic instruments are added in csound-catalog*: fmBass1, fmBass2, dafunkLead and one polyphonic celloSynt. Those instrument serve a good example for building monophonic synthesizers with sharp attacks. Experimental features: - *Arrays, with all opcodes* and functional traversals. See the guide for details details <https://github.com/spell-music/csound-expression/blob/master/tutorial/chapters/BasicTypesTutorial.md#arrays-arr> . - *Imperative style instruments*. With imperative style instruments we can create and invoke the instruments in Csound way. we can create an instrument and get it’s unique identifier. Than we can schedule a note by that identifier. We can create an instrument that produces a sound with function: newOutInstr :: (Arg a, Sigs b) => (a -> SE b) -> SE (InstrRef a, b) It takes in a body of the instrument and gives back an instrument reference and a signal where the output is going to be written. Then we can invoke the notes just like we do it in the Csound with function scheduleEvent: scheduleEvent :: Arg a => InstrRef a -> D -> D -> a -> SE () scheduleEvent instrRed delayStartTime duration arguments It takes in instrument reference, start time from the time of invocation, duration (all in seconds) and miscellaneous arguments. Notice that the instrument reference is parametrized by the type of arguments. This way we can not feed the wrong messages to the instrument. Also we can create procedures that produce no output but do something useful: newInstr :: Arg a => (a -> SE ()) -> SE (InstrRef a) ------------------------------ Happy Haskelling! Anton ------------------------------ Links to the library: https://hackage.haskell.org/package/csound-expression See the guide at github: https://github.com/spell-music/csound-expression
Ah right, a little bit of a pity that Patterns of Rationals can't be expressed like this, but as (1/3) seems to be interpreted the same as (1%3) without floating point error, no biggy. I wrote a blog post about this including a quick video demo: https://slab.org/patterns-are-the-time-of-numbers/ It feels really nice to have Patterns in the Num class, a huge, unexpected improvement. cheers On 6 March 2017 at 12:15, Henning Thielemann
<email obscured>> wrote: > > On Mon, 6 Mar 2017, Alex McLean wrote: > >> Hmm, the only snag I've found is that this works: >> 1/3 :: Pattern Rational >> >> but this doesn't: >> (1%3) :: Pattern Rational > > Sure, but this is true for all Fractional types except Ratio, e.g. > > (1%3) :: Double > > is forbidden, as well. > > -- > > Read the whole topic here: Haskell Art: > http://lurk.org/r/topic/6kyTKyeDzZF0lWDK5mk8U0 > > To leave Haskell Art, email <email obscured> with the following email subject: unsubscribe -- blog: http://slab.org/ music: http://yaxu.org/ crowdfund: http://www.pledgemusic.com/projects/spicule/
On Mon, 6 Mar 2017, Alex McLean wrote: > Hmm, the only snag I've found is that this works: > 1/3 :: Pattern Rational > > but this doesn't: > (1%3) :: Pattern Rational Sure, but this is true for all Fractional types except Ratio, e.g. (1%3) :: Double is forbidden, as well.
On Mon, Mar 06, 2017 at 11:02:21AM +0000, Alex McLean wrote: > Thanks, my knowledge of Haskell can feel quite surface level when I > read things about monoids etc but if there's a particular library > doing this I'd like to take a look! Ah, the trick is pretty simple, a function which returns a monoid is a monoid itself, and this property lets you have functions that can take a variable number of arguments, like expressed here .  https://wiki.haskell.org/Varargs Now I am not sure if it does apply to your case (especially: if it typechecks or explodes).
Hmm, the only snag I've found is that this works: 1/3 :: Pattern Rational but this doesn't: (1%3) :: Pattern Rational
On 6 March 2017 at 11:53, Alex McLean <email obscured>> wrote: >> The type class for fraction literals is Fractional. > > Aha! > > instance (Fractional a) => Fractional (Pattern a) where > fromRational = pure . fromRational > (/) = liftA2 (/) > > This seems to have done it! Hoping to not hit more snags. Thanks again > Hennig, I have tears in my eyes > > alex -- blog: http://slab.org/ music: http://yaxu.org/ crowdfund: http://www.pledgemusic.com/projects/spicule/
> The type class for fraction literals is Fractional. Aha! instance (Fractional a) => Fractional (Pattern a) where fromRational = pure . fromRational (/) = liftA2 (/) This seems to have done it! Hoping to not hit more snags. Thanks again Hennig, I have tears in my eyes
On 6 March 2017 at 11:37, Alex McLean <email obscured>> wrote: > On 6 March 2017 at 11:25, Henning Thielemann > <email obscured>> wrote: >> On Mon, 6 Mar 2017, Alex McLean wrote: >>> :set -XFlexibleInstances >>> >>> instance Num a => Num (Pattern a) where >> >> If there is sensible arithmetic on Patterns, then go this route. But it is >> plain Haskell 98 instance, no FlexibleInstances - which is good. > > Aha! The only downer is that this only works with bare integers, so > `density' 1.5 ...` doesn't work. Do you have any pointers for how I > could get around this? Perhaps I need to make Pattern a an instance of > Real and Rational as well? Hmm, of course this doesn't work as Real and Rational aren't type classes..
On Mon, 6 Mar 2017, Alex McLean wrote: > On 6 March 2017 at 11:25, Henning Thielemann > <email obscured>> wrote: >> On Mon, 6 Mar 2017, Alex McLean wrote: >>> :set -XFlexibleInstances >>> >>> instance Num a => Num (Pattern a) where >> >> If there is sensible arithmetic on Patterns, then go this route. But it is >> plain Haskell 98 instance, no FlexibleInstances - which is good. > > Aha! The only downer is that this only works with bare integers, so > `density' 1.5 ...` doesn't work. Do you have any pointers for how I > could get around this? Perhaps I need to make Pattern a an instance of > Real and Rational as well? The type class for fraction literals is Fractional.
On 6 March 2017 at 11:25, Henning Thielemann <email obscured>> wrote: > On Mon, 6 Mar 2017, Alex McLean wrote: >> :set -XFlexibleInstances >> >> instance Num a => Num (Pattern a) where > > If there is sensible arithmetic on Patterns, then go this route. But it is > plain Haskell 98 instance, no FlexibleInstances - which is good. Aha! The only downer is that this only works with bare integers, so `density' 1.5 ...` doesn't work. Do you have any pointers for how I could get around this? Perhaps I need to make Pattern a an instance of Real and Rational as well? Best wishes
On Mon, 6 Mar 2017, Alex McLean wrote: > :set -XFlexibleInstances > > instance Num a => Num (Pattern a) where If there is sensible arithmetic on Patterns, then go this route. But it is plain Haskell 98 instance, no FlexibleInstances - which is good.
Hi Hennig On 6 March 2017 at 10:35, Henning Thielemann <email obscured>> wrote: > Btw. you can omit TypeSynonymInstances if you have FlexibleInstances. > Your posted code does not need RankNTypes. Ah I've been collecting these while experimenting. Cargo cult programming ftw! > An alternative would be to fix the type of the first parameter of > 'density' to Pattern Time and define instance Num (Pattern time), such > that the literal 2 is interpreted as Pattern Time. However, I consider it > abuse of the Num class because you will be hardly able to define sensible > arithmetic on "Pattern time". Oh my ... *click* :set -XFlexibleInstances instance Num a => Num (Pattern a) where negate = fmap negate (+) = liftA2 (+) (*) = liftA2 (*) fromInteger = pure . fromInteger abs = fmap abs signum = fmap signum Thanks so much for all the other insightful thoughts but this makes total sense to me so far, seems to sidestep my issue with parameters and as a huge added bonus allows me to do things like `sine1 + (0.5 <~ sine1)`.. This is amazing! Thanks again!
Hi Francesco, > this message won't be of much help, but if you post in > haskell-cafe with an .hs attached I am sure more eyes will > see it (and look at it). I thought about posting to haskell-cafe, but thought people here would understand the problem better, and generally like smaller communnities! However I did also post it on the haskell reddit: https://www.reddit.com/r/haskell/comments/5xshvm/polymorphic_parameters_and_type_inference/ > I didn't have time to test (yet!) but maybe there is a way to > solve this using the monoidal trick many libraries use (or > something else: I would be surprised if no-one encountered > the same problem on -cafe). Thanks, my knowledge of Haskell can feel quite surface level when I read things about monoids etc but if there's a particular library doing this I'd like to take a look!
On Mon, Mar 06, 2017 at 10:06:57AM +0000, Alex McLean wrote: > Hi all, > > I'm struggling with an issue in TidalCycles, a DSL for (mostly > musical) pattern, embedded in haskell. Hello Alex, this message won't be of much help, but if you post in haskell-cafe with an .hs attached I am sure more eyes will see it (and look at it). I didn't have time to test (yet!) but maybe there is a way to solve this using the monoidal trick many libraries use (or something else: I would be surprised if no-one encountered the same problem on -cafe). Happy live coding -F
On Mon, 6 Mar 2017, Alex McLean wrote: > What I'd *love* to do is make it so functions like density could > either take a number, or a pattern of numbers for its first argument. > > Indeed, this works fine: > > :set -XTypeSynonymInstances -XFlexibleInstances -XRankNTypes Btw. you can omit TypeSynonymInstances if you have FlexibleInstances. Your posted code does not need RankNTypes.
> class Temporal a where > toTimePattern :: a -> Pattern Time > > instance Temporal Time where > toTimePattern = pure > > instance Temporal (Pattern Time) where > toTimePattern = id > > let density' :: Temporal a => a -> Pattern b -> Pattern b > density' t p = do t' <- toTimePattern t > density t' p > > Then these are possible, great! > > density' (p "2 3" :: Pattern Time) "bd sn" > density' (2 :: Time) "bd sn" An alternative would be to fix the type of the first parameter of 'density' to Pattern Time and define instance Num (Pattern time), such that the literal 2 is interpreted as Pattern Time. However, I consider it abuse of the Num class because you will be hardly able to define sensible arithmetic on "Pattern time". You can save the type annotation in the first case, if the result of p has fixed type "Pattern Time". If it has partly polymorphic type, i.e. "Pattern time", then you can still define the instance as: instance (time ~ Time) => Temporal (Pattern time) where toTimePattern = id This requires TypeFamilies instead of FlexibleInstances. Generally, my experience is that too much type hacks must be paid with more type annotations. I would certainly prefer a less type-hacked approach. E.g. using your 'pure' does not look worse than a type annotation: density (pure 2) "bd sn" Alternatively, you could define different versions of density'. If there are more functions that could have either pattern or simple time as first parameter, you could write a modifier like so density' "2 3" "bd sn" timed density' 2 "bd sn" with density' :: Pattern Time -> Pattern b -> Pattern b timed :: (Pattern Time -> f) -> (Time -> f) > Asking on the #haskell irc channel, it seems this behaviour is > expected, and that it's not possible to do inference across type > classes. However, it is! But it's patchy.. In the following example, > testA works (for String and Integer), and testB doesn't (for Int). > > class Foo a where > testA :: a -> String > > instance Foo Integer where > testA = show > > instance Foo String where > testA = show > > testA "4" -- works > testA 4 -- works It is not very nice though, since type defaulting jumps in here. It is controlled by the 'default' declaration. It is rarely used and there is a warning if the compiler has to use it.
Hi all, I'm struggling with an issue in TidalCycles, a DSL for (mostly musical) pattern, embedded in haskell. As an example, there's a function `density` of type `density :: Time -> Pattern a -> Pattern a`. `Time` is a type synonym for `Rational`. The `sine` function is of type `Pattern Double`, and returns a sine wave with a frequency of one per cycle. `density 3 sine` would then return a sine wave with a frequency of three. What I'd *love* to do is make it so functions like density could either take a number, or a pattern of numbers for its first argument. Indeed, this works fine: :set -XTypeSynonymInstances -XFlexibleInstances -XRankNTypes class Temporal a where toTimePattern :: a -> Pattern Time instance Temporal Time where toTimePattern = pure instance Temporal (Pattern Time) where toTimePattern = id let density' :: Temporal a => a -> Pattern b -> Pattern b density' t p = do t' <- toTimePattern t density t' p Then these are possible, great! density' (p "2 3" :: Pattern Time) "bd sn" density' (2 :: Time) "bd sn" However, type inference doesn't work - if I remove the type declarations there then the compiler breaks. This is actually a dealbreaker, as tidal is designed for live coding, type inference is an essential timesaver. Asking on the #haskell irc channel, it seems this behaviour is expected, and that it's not possible to do inference across type classes. However, it is! But it's patchy.. In the following example, testA works (for String and Integer), and testB doesn't (for Int). class Foo a where testA :: a -> String instance Foo Integer where testA = show instance Foo String where testA = show testA "4" -- works testA 4 -- works class Bar a where testB :: a -> String instance Bar Int where testB = show testB 4 -- doesn't work Indeed, as far as I can tell the standard `show` function works just great with its polymorphic parameter.. Although I can't see anything in its definition to see why it works (and why it doesn't with my Temporal example). I'm really keen to get this to work as it would give a real step change in the flexibility of Tidal.. Any ideas much appreciated Cheers alex  Here's the error: 218:1: Could not deduce (Temporal a0) arising from a use of ‘density'’ from the context (Parseable b) bound by the inferred type of it :: Parseable b => Pattern b at <interactive>:218:1-20 The type variable ‘a0’ is ambiguous Note: there are several potential instances: instance Temporal Time -- Defined at <interactive>:107:10 instance Temporal (Pattern Time) -- Defined at <interactive>:96:10 In the expression: density' (2) "bd sn" In an equation for ‘it’: it = density' (2) "bd sn" <interactive>:218:11: Could not deduce (Num a0) arising from the literal ‘2’ from the context (Parseable b) bound by the inferred type of it :: Parseable b => Pattern b at <interactive>:218:1-20 The type variable ‘a0’ is ambiguous Note: there are several potential instances: instance Integral a => Num (Ratio a) -- Defined in ‘GHC.Real’ instance Num Integer -- Defined in ‘GHC.Num’ instance Num network-188.8.131.52:Network.Socket.Types.PortNumber -- Defined in ‘network-184.108.40.206:Network.Socket.Types’ ...plus five others In the first argument of ‘density'’, namely ‘(2)’ In the expression: density' (2) "bd sn" In an equation for ‘it’: it = density' (2) "bd sn"