Zulip Chat Archive
Stream: new members
Topic: monadic side-computation
Rob Simmons (Aug 01 2025 at 16:13):
This is mostly an unfamiliarity-with-monad-y-functional programming question.
inductive Tree where
| node : String → Tree → Tree → Tree
| leaf : Tree
def height
| Tree.leaf => 0
| Tree.node _str t1 t2 => Nat.max (height t1) (height t2)
If I want height to return a "side computation" that is a HashSet of all the strings in the tree — I think the return type would be something like State (HashSet String) Nat instead of Nat — what's the right/idiomatic way to go about that?
Aaron Liu (Aug 01 2025 at 16:14):
Aaron Liu (Aug 01 2025 at 16:14):
also don't use Nat.max
Aaron Liu (Aug 01 2025 at 16:15):
you should just write max instead
Rob Simmons (Aug 01 2025 at 16:17):
Right, the max was just a standin for what I'm really doing
Rob Simmons (Aug 01 2025 at 16:20):
interesting — the state monad does more than I actually want; it allows reads and writes (sequentalizing computation) — there's a read-only specialization of state and a write-only specialization of state that are conceptually more "parallel" — this is maybe Appliciative in Haskell? — but is that not Lean-standard style?
Aaron Liu (Aug 01 2025 at 16:23):
Aaron Liu (Aug 01 2025 at 16:24):
there's also the monad transformer versions if you want to add functionality to an existing monad
Rob Simmons (Aug 01 2025 at 16:33):
Okay, so with StateT it looks like this is the move, am I missing any idiomatic improvments?
import Std.Data.HashSet
open Std
inductive Tree where
| node : String → Tree → Tree → Tree
| leaf : Tree
def height : Tree → StateM (HashSet String) Nat
| Tree.leaf => pure 0
| Tree.node str t1 t2 => do
let _ ← set (HashSet.insert (← get) str)
Nat.max <$> height t1 <*> height t2
Aaron Liu (Aug 01 2025 at 16:38):
import Std.Data.HashSet
open Std
inductive Tree where
| node : String → Tree → Tree → Tree
| leaf : Tree
def height : Tree → StateM (HashSet String) Nat
| Tree.leaf => pure 0
| Tree.node str t1 t2 => do
modify fun s => s.insert str
max <$> height t1 <*> height t2
Aaron Liu (Aug 01 2025 at 16:38):
it makes sure you avoid copying the hash set
Rob Simmons (Aug 01 2025 at 16:42):
thank you!
Last updated: Dec 20 2025 at 21:32 UTC