<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	
	>
<channel>
	<title>Comments on: Sequences, segments, and signals</title>
	<atom:link href="http://conal.net/blog/posts/sequences-segments-and-signals/feed" rel="self" type="application/rss+xml" />
	<link>http://conal.net/blog/posts/sequences-segments-and-signals</link>
	<description>Inspirations &#38; experiments, mainly about denotative/functional programming in Haskell</description>
	<lastBuildDate>Sat, 26 Sep 2020 21:06:12 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=4.1.17</generator>
	<item>
		<title>By: conal</title>
		<link>http://conal.net/blog/posts/sequences-segments-and-signals#comment-268</link>
		<dc:creator><![CDATA[conal]]></dc:creator>
		<pubDate>Fri, 19 Dec 2008 04:50:15 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=67#comment-268</guid>
		<description><![CDATA[&lt;p&gt;@sclv,&lt;/p&gt;

&lt;p&gt;Yes indeed.  Many thanks for catching these bugs.  Fixed now in the text.&lt;/p&gt;
]]></description>
		<content:encoded><![CDATA[<p>@sclv,</p>

<p>Yes indeed.  Many thanks for catching these bugs.  Fixed now in the text.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: sclv</title>
		<link>http://conal.net/blog/posts/sequences-segments-and-signals#comment-267</link>
		<dc:creator><![CDATA[sclv]]></dc:creator>
		<pubDate>Thu, 18 Dec 2008 14:12:45 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=67#comment-267</guid>
		<description><![CDATA[&lt;p&gt;another bug. in the applicative instance, you have:&lt;/p&gt;

&lt;pre&gt;
   (fs’,fs”) = splitAt fd fs
   (xs’,xs”) = splitAt xd xs
&lt;/pre&gt;

&lt;p&gt;The fd and the xd are reversed.&lt;/p&gt;
]]></description>
		<content:encoded><![CDATA[<p>another bug. in the applicative instance, you have:</p>

<pre>
   (fs’,fs”) = splitAt fd fs
   (xs’,xs”) = splitAt xd xs
</pre>

<p>The fd and the xd are reversed.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Conal Elliott &#187; Blog Archive &#187; Trimming inputs in functional reactive programming</title>
		<link>http://conal.net/blog/posts/sequences-segments-and-signals#comment-266</link>
		<dc:creator><![CDATA[Conal Elliott &#187; Blog Archive &#187; Trimming inputs in functional reactive programming]]></dc:creator>
		<pubDate>Sat, 13 Dec 2008 21:27:15 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=67#comment-266</guid>
		<description><![CDATA[&lt;p&gt;[...] If we switch from absolute time to relative time, then trimming becomes something with familiar semantics, namely drop, as generalized and used in two of my previous posts, Sequences, streams, and segments and Sequences, segments, and signals. [...]&lt;/p&gt;
]]></description>
		<content:encoded><![CDATA[<p>[&#8230;] If we switch from absolute time to relative time, then trimming becomes something with familiar semantics, namely drop, as generalized and used in two of my previous posts, Sequences, streams, and segments and Sequences, segments, and signals. [&#8230;]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: sclv</title>
		<link>http://conal.net/blog/posts/sequences-segments-and-signals#comment-265</link>
		<dc:creator><![CDATA[sclv]]></dc:creator>
		<pubDate>Fri, 12 Dec 2008 16:24:18 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=67#comment-265</guid>
		<description><![CDATA[&lt;p&gt;Here are some functions I&#039;ve found useful so far in working with signals. You might be able to clean them up and generalize them further. They work for my purposes, but feel a little overconstrained in their types at the moment.&lt;/p&gt;

&lt;pre&gt;
-- A time series association list into a signal
aList2Sig :: Num a =&gt; [(a, b)] -&gt; a :-&gt; b
aList2Sig = S . uncurry (zipWith (t a -&gt; FS t (const a))) . first makeSeries . unzip
    where makeSeries xs = zipWith (-) xs (0:xs)

-- A times series association list into a signal, with linear interpolation
aList2InterpSig :: Fractional a =&gt; [(a, a)] -&gt; a :-&gt; a
aList2InterpSig xs = S $ zipWith interp ((0,0):xs) xs

interp :: Fractional b =&gt; (b,b) -&gt; (b,b) -&gt; b :-&gt;# b
interp (x,y) (x&#039;,y&#039;) = FS dx $ x&#039;&#039; -&gt; ((y&#039; - y) / dx) * x&#039;&#039; + y
    where dx = x&#039; - x


-- Takes a bijection (could use TypeCompose for full effect) and alters the signal such that
-- its input is now that bijection. This only works on signals and not general segments.
-- There should be some way to generalize it with a typeclass, but I&#039;m not sure how.
-- Arrows might help? class Bijectable where...?

changeInput :: (s -&gt; t) -&gt; (t -&gt; s) -&gt; (s :-&gt; a) -&gt; t :-&gt; a
changeInput  g g&#039; = inS . map $ (FS t f) -&gt; FS (g t) (f . g&#039;)

-- Using the bijection machinery, scales a signal over time. 
-- (scaling over the y axis is just via fmap)
scaleBy :: (Fractional s) =&gt; s -&gt; (s :-&gt; a) -&gt; s :-&gt; a
scaleBy v = changeInput (v*) (/v)

-- Transformations between relative and absolute representations
-- can be more generalized beyond just days
-- perhaps even as some sort of meta-bijection pair?

atDay :: (RealFrac b) =&gt; Day -&gt; (b :-&gt; a) -&gt; Day :-&gt; a
atDay d = changeInput (flip addDays d . round) (fromIntegral . flip diffDays d)

relativeFrom :: (RealFrac b) =&gt; Day -&gt; (Day :-&gt; a) -&gt; b :-&gt; a
relativeFrom d = changeInput (fromIntegral . flip diffDays d) (flip addDays d . round)

-- Class of things whose values can be sampled

class Sample v t a &#124; v -&gt; t a where
    sampleAt :: v -&gt; t -&gt; a
    sampleAts :: v -&gt; [t] -&gt; [a]
    sampleAts v = map (sampleAt v)

instance Sample [a] Int a where
    sampleAt = atNote &quot;sampleAt&quot;

instance (Num t, Ord t) =&gt; Sample (t :-&gt; a) t a where
    sampleAt  (S xs) t  = mconcat xs `sampleAt`  t
    sampleAts (S xs) ts = mconcat xs `sampleAts` ts

-- Use the Chart library (previous version [0.8]) to plot signals over inputs.

plotSig :: Sample v Double Double =&gt; String -&gt; v -&gt; [Double] -&gt; Double -&gt; Renderable
plotSig t v ts maxval = toRenderable $ defaultLayout1 {
                          layout1_title           = t,
                          layout1_horizontal_axes = linkedAxes (autoScaledAxis defaultAxis),
                          layout1_vertical_axes   = linkedAxes (autoScaledAxis defaultAxis),
                          layout1_plots = [(&quot;&quot;,HA_Bottom,VA_Left,toPlot myPlot),
                                           (&quot;&quot;,HA_Bottom,VA_Left,toPlot myFillPlot)]
                }
    where myPlot = defaultPlotLines {
                     plot_lines_values = [filter ((Point _ y) -&gt; y &lt;= maxval) $ zipWith Point ts (v `sampleAts` ts)]
                   }
          myFillPlot = defaultPlotPoints {
                         plot_points_style=filledCircles 2 (Color 1 0 0),
                         plot_points_values=[Point 0 0, Point (maximum ts) maxval]
                       }
&lt;/pre&gt;
]]></description>
		<content:encoded><![CDATA[<p>Here are some functions I&#8217;ve found useful so far in working with signals. You might be able to clean them up and generalize them further. They work for my purposes, but feel a little overconstrained in their types at the moment.</p>

<pre>
-- A time series association list into a signal
aList2Sig :: Num a =&gt; [(a, b)] -&gt; a :-&gt; b
aList2Sig = S . uncurry (zipWith (t a -&gt; FS t (const a))) . first makeSeries . unzip
    where makeSeries xs = zipWith (-) xs (0:xs)

-- A times series association list into a signal, with linear interpolation
aList2InterpSig :: Fractional a =&gt; [(a, a)] -&gt; a :-&gt; a
aList2InterpSig xs = S $ zipWith interp ((0,0):xs) xs

interp :: Fractional b =&gt; (b,b) -&gt; (b,b) -&gt; b :-&gt;# b
interp (x,y) (x',y') = FS dx $ x'' -&gt; ((y' - y) / dx) * x'' + y
    where dx = x' - x


-- Takes a bijection (could use TypeCompose for full effect) and alters the signal such that
-- its input is now that bijection. This only works on signals and not general segments.
-- There should be some way to generalize it with a typeclass, but I'm not sure how.
-- Arrows might help? class Bijectable where...?

changeInput :: (s -&gt; t) -&gt; (t -&gt; s) -&gt; (s :-&gt; a) -&gt; t :-&gt; a
changeInput  g g' = inS . map $ (FS t f) -&gt; FS (g t) (f . g')

-- Using the bijection machinery, scales a signal over time. 
-- (scaling over the y axis is just via fmap)
scaleBy :: (Fractional s) =&gt; s -&gt; (s :-&gt; a) -&gt; s :-&gt; a
scaleBy v = changeInput (v*) (/v)

-- Transformations between relative and absolute representations
-- can be more generalized beyond just days
-- perhaps even as some sort of meta-bijection pair?

atDay :: (RealFrac b) =&gt; Day -&gt; (b :-&gt; a) -&gt; Day :-&gt; a
atDay d = changeInput (flip addDays d . round) (fromIntegral . flip diffDays d)

relativeFrom :: (RealFrac b) =&gt; Day -&gt; (Day :-&gt; a) -&gt; b :-&gt; a
relativeFrom d = changeInput (fromIntegral . flip diffDays d) (flip addDays d . round)

-- Class of things whose values can be sampled

class Sample v t a | v -&gt; t a where
    sampleAt :: v -&gt; t -&gt; a
    sampleAts :: v -&gt; [t] -&gt; [a]
    sampleAts v = map (sampleAt v)

instance Sample [a] Int a where
    sampleAt = atNote "sampleAt"

instance (Num t, Ord t) =&gt; Sample (t :-&gt; a) t a where
    sampleAt  (S xs) t  = mconcat xs `sampleAt`  t
    sampleAts (S xs) ts = mconcat xs `sampleAts` ts

-- Use the Chart library (previous version [0.8]) to plot signals over inputs.

plotSig :: Sample v Double Double =&gt; String -&gt; v -&gt; [Double] -&gt; Double -&gt; Renderable
plotSig t v ts maxval = toRenderable $ defaultLayout1 {
                          layout1_title           = t,
                          layout1_horizontal_axes = linkedAxes (autoScaledAxis defaultAxis),
                          layout1_vertical_axes   = linkedAxes (autoScaledAxis defaultAxis),
                          layout1_plots = [("",HA_Bottom,VA_Left,toPlot myPlot),
                                           ("",HA_Bottom,VA_Left,toPlot myFillPlot)]
                }
    where myPlot = defaultPlotLines {
                     plot_lines_values = [filter ((Point _ y) -&gt; y &lt;= maxval) $ zipWith Point ts (v `sampleAts` ts)]
                   }
          myFillPlot = defaultPlotPoints {
                         plot_points_style=filledCircles 2 (Color 1 0 0),
                         plot_points_values=[Point 0 0, Point (maximum ts) maxval]
                       }
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: conal</title>
		<link>http://conal.net/blog/posts/sequences-segments-and-signals#comment-264</link>
		<dc:creator><![CDATA[conal]]></dc:creator>
		<pubDate>Tue, 09 Dec 2008 20:08:06 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=67#comment-264</guid>
		<description><![CDATA[&lt;p&gt;@sclv: Thanks for the encouragement!  And for catching my drop/take default swap.  Fixed now in the post and code.&lt;/p&gt;
]]></description>
		<content:encoded><![CDATA[<p>@sclv: Thanks for the encouragement!  And for catching my drop/take default swap.  Fixed now in the post and code.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: sclv</title>
		<link>http://conal.net/blog/posts/sequences-segments-and-signals#comment-263</link>
		<dc:creator><![CDATA[sclv]]></dc:creator>
		<pubDate>Tue, 09 Dec 2008 18:50:21 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=67#comment-263</guid>
		<description><![CDATA[&lt;p&gt;Great series! This stuff is very useful. The default definitions for drop and take are backwards, by the way.&lt;/p&gt;
]]></description>
		<content:encoded><![CDATA[<p>Great series! This stuff is very useful. The default definitions for drop and take are backwards, by the way.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: newsham</title>
		<link>http://conal.net/blog/posts/sequences-segments-and-signals#comment-262</link>
		<dc:creator><![CDATA[newsham]]></dc:creator>
		<pubDate>Sun, 07 Dec 2008 18:24:57 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=67#comment-262</guid>
		<description><![CDATA[&lt;p&gt;I think most programmers (myself included) would have gone straight to this efficient implementation when writing the function. I really like the approach you&#039;ve taken and I see it as a strength of your semantic design approach.  You started out with an implementation that was more principled and closer to the semantics you were going after and then refined it using the first implementation as a model to guide the efficient implementation.  This gave you more time to work with the underlying ideas and gain insights into it (ie. taking longer is a benefit here). Then when you wrote the efficient implementation, you checked your work, something most programmers (myself included) wouldn&#039;t have done if they jumped right into the efficient implementation.  Further, the first model provided a means to check the work!  The traditional approach would have a programmer do the work in his head and never make the reasoning explicit and probably leave this crucial part of the design undocumented.&lt;/p&gt;
]]></description>
		<content:encoded><![CDATA[<p>I think most programmers (myself included) would have gone straight to this efficient implementation when writing the function. I really like the approach you&#8217;ve taken and I see it as a strength of your semantic design approach.  You started out with an implementation that was more principled and closer to the semantics you were going after and then refined it using the first implementation as a model to guide the efficient implementation.  This gave you more time to work with the underlying ideas and gain insights into it (ie. taking longer is a benefit here). Then when you wrote the efficient implementation, you checked your work, something most programmers (myself included) wouldn&#8217;t have done if they jumped right into the efficient implementation.  Further, the first model provided a means to check the work!  The traditional approach would have a programmer do the work in his head and never make the reasoning explicit and probably leave this crucial part of the design undocumented.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: conal</title>
		<link>http://conal.net/blog/posts/sequences-segments-and-signals#comment-261</link>
		<dc:creator><![CDATA[conal]]></dc:creator>
		<pubDate>Fri, 05 Dec 2008 20:56:43 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=67#comment-261</guid>
		<description><![CDATA[&lt;p&gt;@Matt: Beautiful notation!!&lt;/p&gt;

&lt;p&gt;Maybe also&lt;/p&gt;

&lt;p&gt;&lt;div&gt;
&lt;pre class=&quot;haskell&quot;&gt;&lt;span style=&quot;color: green;&quot;&gt;&#040;&lt;/span&gt;&lt;~&lt;span style=&quot;color: green;&quot;&gt;&#041;&lt;/span&gt; = &lt;a href=&quot;http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:flip&quot; rel=&quot;nofollow&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;flip&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;color: green;&quot;&gt;&#040;&lt;/span&gt;~&gt;&lt;span style=&quot;color: green;&quot;&gt;&#041;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;for things like &lt;code&gt;S &lt;~ unS&lt;/code&gt;, when someone is in a left-to-right mood.&lt;/p&gt;
]]></description>
		<content:encoded><![CDATA[<p>@Matt: Beautiful notation!!</p>

<p>Maybe also</p>

<p><div>
<pre class="haskell"><span style="color: green;">&#40;</span>&lt;~<span style="color: green;">&#41;</span> = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:flip" rel="nofollow"><span style="font-weight: bold;">flip</span></a> <span style="color: green;">&#40;</span>~&gt;<span style="color: green;">&#41;</span></pre>
</div></p>

<p>for things like <code>S &lt;~ unS</code>, when someone is in a left-to-right mood.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Matt Hellige</title>
		<link>http://conal.net/blog/posts/sequences-segments-and-signals#comment-260</link>
		<dc:creator><![CDATA[Matt Hellige]]></dc:creator>
		<pubDate>Fri, 05 Dec 2008 16:59:17 +0000</pubDate>
		<guid isPermaLink="false">http://conal.net/blog/?p=67#comment-260</guid>
		<description><![CDATA[&lt;p&gt;As I describe &lt;a href=&quot;http://matt.immute.net/content/pointless-fun&quot; rel=&quot;nofollow&quot;&gt;here&lt;/a&gt;, I&#039;d prefer to write:&lt;/p&gt;

&lt;pre&gt;
inS = unS ~&gt; S
inS2 = unS ~&gt; unS ~&gt; S
-- or...
inS2&#039; = unS ~&gt; inS
&lt;/pre&gt;

&lt;p&gt;To my eyes, it doesn&#039;t get much better than that.&lt;/p&gt;
]]></description>
		<content:encoded><![CDATA[<p>As I describe <a href="http://matt.immute.net/content/pointless-fun" rel="nofollow">here</a>, I&#8217;d prefer to write:</p>

<pre>
inS = unS ~&gt; S
inS2 = unS ~&gt; unS ~&gt; S
-- or...
inS2' = unS ~&gt; inS
</pre>

<p>To my eyes, it doesn&#8217;t get much better than that.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
