type Action = Tick | Toggle | NoOp
Timer will create Tick values, button will create Toggle values, NoOp is here because Elm signals require some initial value.
So now timer signal would look like this:
ticks = Signal.map (\_ -> Tick) (Time.every Time.second)
And, as you've correctly noticed we would then merge two signals with Signal.merge:
actions = Signal.merge clicks ticks
How to get clicks, you would ask? Mailbox will help us.. Mailbox gives us a signal from address. And address is what Html.Events.onClick can throw stuff at:
mailbox = Signal.mailbox NoOp
clicks : Signal Action
clicks = mailbox.signal
Our button would now be able to produce those clicks:
import Html.Events exposing (onClick)
button [ onClick address Toggle ] [ … ]
Now we want to model the problem a little better than with just a single integer. We need to track if our timer is running or not:
type alias Model = { running: Bool, count: Int}
At the beginning our timer would be at "running" state, with 0 count:
model : Model
model = {running = True, count = 0}
Now we can call foldp to get current model signal from actions:
model_signal : Signal Model
model_signal = Signal.foldp update model actions
update is a more complicated version of your (\_ state -> state + 1). Compared to your version it takes an addtional argument - action (which is Tick, Toggle or NoOp):
update : Action -> Model -> Model