I did this same thing in Clojure a while back as a way to introduce myself to the language. As you can see in the card definitions from that [1], I arrived at something close to your proposed idiom. All spells and battlecries are functions of the game state that usually end up being described as the composition of basic actions in hearthstone, e.g. (target [:type]) (damage-target n).
If I may, I would suggest thinking about things in a way very similar to how Magic: The Gathering does, which is as a "state-based effect" or "triggered effect". This models very well into programming as event handlers watching state-changes and acting appropriately.
For instance, the most common state-based effect in MTG is death from damage. This is perhaps even easier to model in Hearthstone, as damage is persistent. Simply register event handlers on minions which get called whenever the health of a minion changes; if it's <= 0, trigger death.
Death will then cause any "triggered effects" to fire, such as a deathrattle tigger. This is also easy; just a listener on the death event.
The event/listener paradigm is an interesting way of going about this, and I considered doing it that way at the beginning. But, after some thinking and experimenting, I found the "card use -> modify BoardState" way more straight forward, especially since it leads to a nice recursive tree structure for the game AI engine. The primary goal of this simulator is to do statistical analysis on deck performance, so I think it's a decent way of going about it. On the other hand, if my goal were to create an actual playable game clone, I probably would have taken the event/listener approach.
1. https://github.com/Mischanix/soot/blob/master/src/soot/cards...