bodil / purescript-signal

Elm style FRP library for PureScript
Apache License 2.0
258 stars 44 forks source link

channel type signature, what the Eff? #27

Closed Fresheyeball closed 9 years ago

Fresheyeball commented 9 years ago

So channel :: forall a e. a -> Eff (chan :: Chan | e) (Channel a) is the current type signature for channel. But the implementation of channel is just using constant which has a type signature of constant :: forall a. a -> Signal a so its not clear why channel has an Eff. Why not

channel :: forall a. a -> Channel a

? (thanks @michaelficarra for helping me understand this)

bodil commented 9 years ago

That would violate referential transparency - every call to channel creates a distinct channel, whereas a -> Channel a implies that every time you call channel with the same value of type a, you'll get the same channel back (or at the very least a channel which behaves exactly like it). The point of channels is that you can push arbitrary values to them, thus you cannot guarantee value equality for two distinct channels once created. That's why the Eff is there.

The reason constant doesn't have an Eff is the same: for any value n of a, you're guaranteed to get a signal which always contains n. It won't be the same signal, given the current implementation, but two signals created using the same value of a will always be value equal. Likewise with foldp et al: calling foldp twice with the same arguments will yield two signals which will always contain the same values.

The fact that channel uses constant as a general signal constructor is an implementation detail. It's untyped in JS, so no assumptions should be made about the type signatures of functions using it inside FFI.

Fresheyeball commented 9 years ago

Thank you, that makes sense.