`f x y = 5`

is a 2-argument function, and `f x = 5`

is a 1-argument function, I thought `f = 5`

must be a 0-argument function. The syntax makes it hard to tell that all functions take exactly one argument.]]>I admit I was hoping you’d covered this base already in your work or knew someone who did .

I’m not sure I have a good enough sense of what you mean by a “precise denotation” to come up with one.

I can think of some of my own approaches to the problem, and I may try some experiments to see what works out in practice, but I’m not sure if they are going to be as “good” as the procedural version.

For example, if the input is given as a list of lines of text and the output is given as a list of lines, then one could have a function from input lines to output lines. Like:

prog [] = ["What is your name?"] prog [name] = (prog []) ++ ["Hello, " ++ name ++ "! How old are you?"] prog [name, age] = (prog [name]) ++ ["Well, you look much younger..."]

Presumably I can devise a function from time to a list of input lines, and pass that into this function to get the output lines.

I know this approach has major flaws, but is this an example of what you mean by casting something in terms of denotation?

]]>`IO`

is not. One way to investigate is to cast something like your `IO`

example in terms of a (precise) denotation, and then see whether/how to capture that denotation in terms of FRP’s which is functions of (continuous) time. I expect that doing so would flush out some hidden assumptions and reveal some alternatives.]]>```
printLine "What is your name?"
name ← readLine
printLine "Hello, " ++ name ++ "! How old are you?"
age ← readLine
printLine "Well, you look much younger..."
```

Is FRP unsuitable for this kind of application?

]]>The basic idea is to represent a 3D object as a “distance field”, i.e. a continuous function from R^3 to R that returns the distance to the object. The value of that function is zero inside the object, and grows as you get further away from it. That technique is well suited to ray marching on the GPU, because when you’re marching along the ray, evaluating the distance field at the current point gives you the size of the next step, so you can make bigger steps when the ray passes far from the object. Simple objects like spheres have distance fields that are easy to define, and simple operations on objects often correspond to simple operations on distance fields. It’s also easy to approximate things like normal direction, ambient occlusion, and even penumbras (send a ray to the light source and note how closely it passed to the occluder).

In a perfect world, we could have a combinator library in Haskell for rendering distance fields that would compile to a single GPU shader program. It’s scary how well this idea fits together.

]]>I don’t know how these compare to the ‘Circuit Category’ C (Kleisli CircuitM (Pins a) (Pins b)).

]]>apply ∷ (a ⇨ b) × a ↝ b tuple ∷ a ↝ (b ⇨ (a × b)) (^^^) ∷ (a ↝ b) → (d ↝ c) → ((c ⇨ a) ↝ (d ⇨ b))

with `curry f = (id ^^^ f) . tuple`

and `uncurry f = apply . (f *** id)`

.

`(^^^)`

is analogous to `(+++)`

and `(***)`

.

I have managed to avoid type instances and “IsSource” constraints with what seems to be a cunning trick. I used `Wire`

rather than `Pins`

, and instead of requiring `Wire`

to be the type constructor in front of every datatype that represents connectors, I just store `Wire`

s in any Haskell datatype, so for example we have `plus :: QueryArr (Wire Int, Wire Int) (Wire Int)`

and `restrict :: QueryArr (Wire Bool) ()`

.

The definition is `data Wire a = Wire String`

, where the string field is the column name of a database table. Typesafety is provided by ensuring that you can only produce a `Wire`

in the context of a table which contains a column which is referred to in the `Wire`

.

This approach has worked very well. I haven’t considered coproducts, but would probably fake them up by representing `A + B ~> X`

as `(A ~> X, B ~> X)`

rather than trying to construct `A + B`

itself.

`A + B -> X`

with `(A -> X, B -> X)`

.]]>