Clean has used uniqueness types since the 80s. Monadic effects were only discovered/implemented in the 90s. In fact, Haskell 1.0 didn't have monadic I/O either; AFAIK it implemented I/O using a "stream of actions", but that doesn't compose very well (e.g. we can get deadlocked if an earlier action depends on the result of a later action)
Uniqueness types are similar to to linear types (as found in Idris, ATS, and recently Haskell), and similar to Rust's 'ownership' model ("affine types"?)
Uniqueness types are similar to to linear types (as found in Idris, ATS, and recently Haskell), and similar to Rust's 'ownership' model ("affine types"?)