or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

data-structures.mdfree-structures.mdindex.mdstd-instances.mdsyntax.mdtransformers.mdtype-classes.md

syntax.mddocs/

0

# Syntax Extensions

1

2

Scalaz provides implicit conversions and operators that extend standard types with functional programming methods, creating a convenient DSL for type class operations.

3

4

## Capabilities

5

6

### Functor Syntax

7

8

Extensions for types with Functor instances.

9

10

```scala { .api }

11

// Available via import scalaz.syntax.functor._ or import scalaz.Scalaz._

12

13

implicit class FunctorOps[F[_], A](self: F[A])(implicit F: Functor[F]) {

14

/** Map over the contained value */

15

def map[B](f: A => B): F[B] = F.map(self)(f)

16

17

/** Alias for map */

18

def <$>[B](f: A => B): F[B] = F.map(self)(f)

19

20

/** Discard the value, keeping structure */

21

def void: F[Unit] = F.void(self)

22

23

/** Pair original with result of function */

24

def fproduct[B](f: A => B): F[(A, B)] = F.fproduct(self)(f)

25

26

/** Replace all values with constant */

27

def as[B](b: => B): F[B] = F.map(self)(_ => b)

28

29

/** Strengthen with value on left */

30

def strengthL[B](b: B): F[(B, A)] = F.map(self)(a => (b, a))

31

32

/** Strengthen with value on right */

33

def strengthR[B](b: B): F[(A, B)] = F.map(self)(a => (a, b))

34

}

35

```

36

37

**Usage Examples:**

38

39

```scala

40

import scalaz._

41

import scalaz.syntax.functor._

42

43

List(1, 2, 3) <$> (_ * 2) // List(2, 4, 6)

44

List(1, 2, 3).void // List((), (), ())

45

List(1, 2, 3).fproduct(_ * 2) // List((1,2), (2,4), (3,6))

46

List(1, 2, 3).as("x") // List("x", "x", "x")

47

```

48

49

### Applicative Syntax

50

51

Extensions for types with Applicative instances.

52

53

```scala { .api }

54

// Available via import scalaz.syntax.applicative._ or import scalaz.Scalaz._

55

56

implicit class ApplicativeOps[F[_], A](self: F[A])(implicit F: Applicative[F]) {

57

/** Applicative builder for combining values */

58

def |@|[B](fb: F[B]): ApplicativeBuilder[F, A, B]

59

60

/** Apply a function in context */

61

def <*>[B](f: F[A => B]): F[B] = F.ap(self)(f)

62

63

/** Sequence and discard left value */

64

def *>[B](fb: F[B]): F[B] = F.apply2(self, fb)((_, b) => b)

65

66

/** Sequence and discard right value */

67

def <*[B](fb: F[B]): F[A] = F.apply2(self, fb)((a, _) => a)

68

}

69

70

implicit class ApplicativeBuilder[F[_], A, B](self: F[A] |@| F[B]) {

71

/** Apply binary function */

72

def apply[C](f: (A, B) => C): F[C]

73

74

/** Extend to ternary */

75

def |@|[C](fc: F[C]): ApplicativeBuilder3[F, A, B, C]

76

77

/** Create tuple */

78

def tupled: F[(A, B)]

79

}

80

81

// Point syntax for lifting values

82

implicit class ApplicativePointOps[A](self: A) {

83

def point[F[_]](implicit F: Applicative[F]): F[A] = F.point(self)

84

def pure[F[_]](implicit F: Applicative[F]): F[A] = F.point(self)

85

}

86

```

87

88

**Usage Examples:**

89

90

```scala

91

import scalaz._

92

import scalaz.syntax.applicative._

93

import scalaz.std.option._

94

95

// Applicative builder

96

val result = (some(1) |@| some(2) |@| some(3))(_ + _ + _) // Some(6)

97

98

// Point syntax

99

42.point[Option] // Some(42)

100

"hello".point[List] // List("hello")

101

102

// Sequencing

103

some(1) *> some(2) // Some(2)

104

some(1) <* some(2) // Some(1)

105

```

106

107

### Monad Syntax

108

109

Extensions for types with Monad instances.

110

111

```scala { .api }

112

// Available via import scalaz.syntax.monad._ or import scalaz.Scalaz._

113

114

implicit class MonadOps[F[_], A](self: F[A])(implicit F: Monad[F]) {

115

/** Monadic bind (flatMap) */

116

def >>=[B](f: A => F[B]): F[B] = F.bind(self)(f)

117

118

/** Alias for bind */

119

def flatMap[B](f: A => F[B]): F[B] = F.bind(self)(f)

120

121

/** Sequence and discard left value */

122

def >>[B](fb: => F[B]): F[B] = F.bind(self)(_ => fb)

123

124

/** Kleisli composition */

125

def >=>[B](f: A => F[B]): A => F[B] = a => F.bind(self)(f)

126

127

/** Join nested monads */

128

def join[B](implicit ev: A <:< F[B]): F[B] = F.join(self.map(ev))

129

130

/** Conditional execution */

131

def whenM(cond: F[Boolean])(implicit F: Monad[F]): F[Unit]

132

def unlessM(cond: F[Boolean])(implicit F: Monad[F]): F[Unit]

133

}

134

135

// Guard and filtering

136

implicit class MonadGuardOps[F[_]](implicit F: MonadPlus[F]) {

137

def guard(condition: Boolean): F[Unit] = F.guard(condition)

138

def prevent(condition: Boolean): F[Unit] = F.guard(!condition)

139

}

140

```

141

142

**Usage Examples:**

143

144

```scala

145

import scalaz._

146

import scalaz.syntax.monad._

147

import scalaz.std.list._

148

149

// Monadic bind

150

List(1, 2) >>= (x => List(x, x * 2)) // List(1, 2, 2, 4)

151

152

// Sequencing

153

List(1, 2) >> List(10, 20) // List(10, 20, 10, 20)

154

155

// For comprehensions work automatically

156

val result = for {

157

x <- List(1, 2)

158

y <- List(10, 20)

159

} yield x + y

160

```

161

162

### Foldable Syntax

163

164

Extensions for types with Foldable instances.

165

166

```scala { .api }

167

// Available via import scalaz.syntax.foldable._ or import scalaz.Scalaz._

168

169

implicit class FoldableOps[F[_], A](self: F[A])(implicit F: Foldable[F]) {

170

/** Fold with monoid */

171

def fold(implicit A: Monoid[A]): A = F.fold(self)

172

173

/** Map and fold */

174

def foldMap[B](f: A => B)(implicit B: Monoid[B]): B = F.foldMap(self)(f)

175

176

/** Right fold */

177

def foldRight[B](z: => B)(f: (A, => B) => B): B = F.foldRight(self, z)(f)

178

179

/** Left fold */

180

def foldLeft[B](z: B)(f: (B, A) => B): B = F.foldLeft(self, z)(f)

181

182

/** Convert to List */

183

def toList: List[A] = F.toList(self)

184

185

/** Length */

186

def length: Int = F.length(self)

187

188

/** Check if all satisfy predicate */

189

def all(p: A => Boolean): Boolean = F.all(self)(p)

190

191

/** Check if any satisfy predicate */

192

def any(p: A => Boolean): Boolean = F.any(self)(p)

193

194

/** Check if empty */

195

def empty: Boolean = F.empty(self)

196

197

/** Find element */

198

def find(p: A => Boolean): Option[A] = F.find(self)(p)

199

200

/** Count elements satisfying predicate */

201

def count(p: A => Boolean): Int = F.count(self)(p)

202

203

/** Sum elements */

204

def sum(implicit A: Monoid[A]): A = F.fold(self)

205

206

/** Product elements */

207

def product(implicit A: Monoid[A]): A = F.fold(self)

208

209

/** Maximum element */

210

def maximum(implicit A: Order[A]): Option[A] = F.maximum(self)

211

212

/** Minimum element */

213

def minimum(implicit A: Order[A]): Option[A] = F.minimum(self)

214

}

215

```

216

217

**Usage Examples:**

218

219

```scala

220

import scalaz._

221

import scalaz.syntax.foldable._

222

import scalaz.std.list._

223

224

List(1, 2, 3, 4).foldMap(_.toString) // "1234"

225

List(1, 2, 3, 4).all(_ > 0) // true

226

List(1, 2, 3, 4).any(_ > 3) // true

227

List(1, 2, 3, 4).count(_ % 2 == 0) // 2

228

List("a", "b", "c").find(_ == "b") // Some("b")

229

```

230

231

### Traverse Syntax

232

233

Extensions for types with Traverse instances.

234

235

```scala { .api }

236

// Available via import scalaz.syntax.traverse._ or import scalaz.Scalaz._

237

238

implicit class TraverseOps[F[_], A](self: F[A])(implicit F: Traverse[F]) {

239

/** Traverse with effects */

240

def traverse[G[_], B](f: A => G[B])(implicit G: Applicative[G]): G[F[B]] = F.traverse(self)(f)

241

242

/** Sequence effects */

243

def sequence[G[_], B](implicit ev: A <:< G[B], G: Applicative[G]): G[F[B]] = F.sequence(self.map(ev))

244

245

/** Map with accumulating state */

246

def mapAccumL[S, B](z: S)(f: (S, A) => (S, B)): (S, F[B]) = F.mapAccumL(self, z)(f)

247

248

/** Map with accumulating state (right) */

249

def mapAccumR[S, B](z: S)(f: (S, A) => (S, B)): (S, F[B]) = F.mapAccumR(self, z)(f)

250

251

/** Reverse the structure */

252

def reverse: F[A] = F.reverse(self)

253

}

254

```

255

256

**Usage Examples:**

257

258

```scala

259

import scalaz._

260

import scalaz.syntax.traverse._

261

import scalaz.std.list._

262

import scalaz.std.option._

263

264

// Traverse with Option

265

List(1, 2, 3).traverse(x => if (x > 0) Some(x * 2) else None) // Some(List(2, 4, 6))

266

267

// Sequence List of Options

268

List(Some(1), Some(2), Some(3)).sequence // Some(List(1, 2, 3))

269

List(Some(1), None, Some(3)).sequence // None

270

```

271

272

### Equal Syntax

273

274

Extensions for types with Equal instances.

275

276

```scala { .api }

277

// Available via import scalaz.syntax.equal._ or import scalaz.Scalaz._

278

279

implicit class EqualOps[A](self: A)(implicit A: Equal[A]) {

280

/** Type-safe equality */

281

def ===(other: A): Boolean = A.equal(self, other)

282

283

/** Type-safe inequality */

284

def /==(other: A): Boolean = !A.equal(self, other)

285

286

/** Assert equality (throws if false) */

287

def assert_===(other: A): A = {

288

if (!A.equal(self, other)) sys.error(s"Assertion failed: $self === $other")

289

self

290

}

291

}

292

```

293

294

**Usage Examples:**

295

296

```scala

297

import scalaz._

298

import scalaz.syntax.equal._

299

import scalaz.std.anyVal._

300

301

1 === 1 // true (uses Equal[Int])

302

1 /== 2 // true

303

"a" === "a" // true (uses Equal[String])

304

305

// Prevents comparison of different types

306

// 1 === "1" // Compilation error!

307

```

308

309

### Order Syntax

310

311

Extensions for types with Order instances.

312

313

```scala { .api }

314

// Available via import scalaz.syntax.order._ or import scalaz.Scalaz._

315

316

implicit class OrderOps[A](self: A)(implicit A: Order[A]) {

317

/** Compare and return Ordering */

318

def ?|?(other: A): Ordering = A.order(self, other)

319

320

/** Less than */

321

def <(other: A): Boolean = A.lessThan(self, other)

322

323

/** Less than or equal */

324

def <=(other: A): Boolean = A.lessThanOrEqual(self, other)

325

326

/** Greater than */

327

def >(other: A): Boolean = A.greaterThan(self, other)

328

329

/** Greater than or equal */

330

def >=(other: A): Boolean = A.greaterThanOrEqual(self, other)

331

332

/** Maximum */

333

def max(other: A): A = A.max(self, other)

334

335

/** Minimum */

336

def min(other: A): A = A.min(self, other)

337

338

/** Sort with another value */

339

def sort(other: A): (A, A) = if (A.lessThanOrEqual(self, other)) (self, other) else (other, self)

340

}

341

```

342

343

**Usage Examples:**

344

345

```scala

346

import scalaz._

347

import scalaz.syntax.order._

348

import scalaz.std.anyVal._

349

350

5 ?|? 3 // Ordering.GT

351

5 > 3 // true

352

5 max 10 // 10

353

5 min 10 // 5

354

5 sort 3 // (3, 5)

355

```

356

357

### Semigroup/Monoid Syntax

358

359

Extensions for types with Semigroup/Monoid instances.

360

361

```scala { .api }

362

// Available via import scalaz.syntax.semigroup._ or import scalaz.Scalaz._

363

364

implicit class SemigroupOps[A](self: A)(implicit A: Semigroup[A]) {

365

/** Semigroup append */

366

def |+|(other: => A): A = A.append(self, other)

367

368

/** Multiply (repeat operation) */

369

def multiply1(n: Int): A = A.multiply1(self, n)

370

}

371

372

// Available via import scalaz.syntax.monoid._ or import scalaz.Scalaz._

373

implicit class MonoidOps[A](self: A)(implicit A: Monoid[A]) {

374

/** Check if zero */

375

def isEmpty: Boolean = A.isMEmpty(self)

376

377

/** Multiply with zero handling */

378

def multiply(n: Int): A = A.multiply(self, n)

379

}

380

381

// Monoid zero

382

implicit class MonoidZeroOps[A](implicit A: Monoid[A]) {

383

def mzero: A = A.zero

384

}

385

```

386

387

**Usage Examples:**

388

389

```scala

390

import scalaz._

391

import scalaz.syntax.monoid._

392

import scalaz.std.string._

393

import scalaz.std.list._

394

395

"Hello" |+| " " |+| "World" // "Hello World"

396

List(1, 2) |+| List(3, 4) // List(1, 2, 3, 4)

397

List(1, 2).multiply(3) // List(1, 2, 1, 2, 1, 2)

398

mzero[String] // ""

399

```

400

401

### Show Syntax

402

403

Extensions for types with Show instances.

404

405

```scala { .api }

406

// Available via import scalaz.syntax.show._ or import scalaz.Scalaz._

407

408

implicit class ShowOps[A](self: A)(implicit A: Show[A]) {

409

/** Convert to string */

410

def shows: String = A.shows(self)

411

412

/** Convert to Cord */

413

def show: Cord = A.show(self)

414

415

/** Print to console */

416

def println: Unit = Predef.println(shows)

417

418

/** Print without newline */

419

def print: Unit = Predef.print(shows)

420

}

421

```

422

423

**Usage Examples:**

424

425

```scala

426

import scalaz._

427

import scalaz.syntax.show._

428

import scalaz.std.anyVal._

429

430

42.shows // "42"

431

42.println // Prints: 42

432

433

// Custom Show instances provide better output than toString

434

case class Person(name: String, age: Int)

435

implicit val personShow: Show[Person] = Show.shows(p => s"${p.name}(${p.age})")

436

Person("John", 30).shows // "John(30)"

437

```

438

439

### Validation Syntax

440

441

Extensions for working with Validation types.

442

443

```scala { .api }

444

// Available via import scalaz.syntax.validation._ or import scalaz.Scalaz._

445

446

implicit class ValidationOps[A](self: A) {

447

/** Create success validation */

448

def success[E]: Validation[E, A] = Success(self)

449

450

/** Create success validation with NonEmptyList error type */

451

def successNel[E]: ValidationNel[E, A] = Success(self)

452

}

453

454

implicit class ValidationErrorOps[E](self: E) {

455

/** Create failure validation */

456

def failure[A]: Validation[E, A] = Failure(self)

457

458

/** Create failure validation with NonEmptyList */

459

def failureNel[A]: ValidationNel[E, A] = Failure(NonEmptyList(self))

460

}

461

```

462

463

**Usage Examples:**

464

465

```scala

466

import scalaz._

467

import scalaz.syntax.validation._

468

import scalaz.syntax.applicative._

469

470

// Creating validations

471

val valid = "John".success[String]

472

val invalid = "Empty name".failure[String]

473

474

// Error accumulation

475

val result = (

476

"John".successNel[String] |@|

477

"Invalid age".failureNel[String] |@|

478

"john@example.com".successNel[String]

479

) { (name, age, email) => User(name, age, email) }

480

```

481

482

### Either/Disjunction Syntax

483

484

Extensions for Either and Disjunction (\/) types.

485

486

```scala { .api }

487

// Available via import scalaz.syntax.either._ or import scalaz.Scalaz._

488

489

implicit class EitherOps[A](self: A) {

490

/** Create left disjunction */

491

def left[B]: A \/ B = -\/(self)

492

493

/** Create right disjunction */

494

def right[B]: B \/ A = \/-(self)

495

}

496

497

implicit class DisjunctionOps[A, B](self: A \/ B) {

498

/** Alias for map */

499

def \/[C](f: B => C): A \/ C = self.map(f)

500

501

/** Get right or default */

502

def |(default: => B): B = self.getOrElse(default)

503

}

504

```

505

506

**Usage Examples:**

507

508

```scala

509

import scalaz._

510

import scalaz.syntax.either._

511

512

val success = 42.right[String] // String \/ Int = \/-(42)

513

val failure = "error".left[Int] // String \/ Int = -\/("error")

514

515

success | 0 // 42

516

failure | 0 // 0

517

```

518

519

### MonadPlus Syntax

520

521

Extensions for types with MonadPlus instances.

522

523

```scala { .api }

524

// Available via import scalaz.syntax.monadPlus._ or import scalaz.Scalaz._

525

526

implicit class MonadPlusOps[F[_], A](self: F[A])(implicit F: MonadPlus[F]) {

527

/** Filter with predicate */

528

def filter(p: A => Boolean): F[A] = F.filter(self)(p)

529

530

/** Alternative operator */

531

def <+>(other: => F[A]): F[A] = F.plus(self, other)

532

533

/** Return this if non-empty, otherwise alternative */

534

def orElse(alternative: => F[A]): F[A] = F.plus(self, alternative)

535

}

536

537

// Empty values

538

implicit class MonadPlusEmptyOps[F[_]](implicit F: MonadPlus[F]) {

539

def empty[A]: F[A] = F.empty[A]

540

}

541

```

542

543

**Usage Examples:**

544

545

```scala

546

import scalaz._

547

import scalaz.syntax.monadPlus._

548

import scalaz.std.list._

549

550

List(1, 2, 3, 4).filter(_ % 2 == 0) // List(2, 4)

551

List(1, 2) <+> List(3, 4) // List(1, 2, 3, 4)

552

List.empty[Int] orElse List(1, 2) // List(1, 2)

553

```

554

555

### Import Strategies

556

557

#### Complete Syntax Import

558

559

```scala { .api }

560

// Import all syntax extensions

561

import scalaz._

562

import Scalaz._

563

564

// Or import syntax package

565

import scalaz.syntax.all._

566

```

567

568

#### Selective Syntax Imports

569

570

```scala { .api }

571

// Import specific syntax

572

import scalaz.syntax.functor._ // Functor operations

573

import scalaz.syntax.applicative._ // Applicative operations

574

import scalaz.syntax.monad._ // Monad operations

575

import scalaz.syntax.foldable._ // Foldable operations

576

import scalaz.syntax.traverse._ // Traverse operations

577

import scalaz.syntax.equal._ // Equal operations

578

import scalaz.syntax.order._ // Order operations

579

import scalaz.syntax.semigroup._ // Semigroup operations

580

import scalaz.syntax.monoid._ // Monoid operations

581

import scalaz.syntax.show._ // Show operations

582

import scalaz.syntax.validation._ // Validation operations

583

import scalaz.syntax.either._ // Either/Disjunction operations

584

```

585

586

#### Combined Imports

587

588

```scala { .api }

589

// Common combination for everyday functional programming

590

import scalaz.{Applicative, Functor, Monad, Equal, Show, \/, ValidationNel}

591

import scalaz.syntax.applicative._

592

import scalaz.syntax.functor._

593

import scalaz.syntax.monad._

594

import scalaz.syntax.equal._

595

import scalaz.syntax.validation._

596

import scalaz.std.option._

597

import scalaz.std.list._

598

import scalaz.std.string._

599

```

600

601

**Usage Examples:**

602

603

```scala

604

import scalaz._

605

import Scalaz._

606

607

// All syntax available

608

val result = List(1, 2, 3)

609

.map(_ * 2) // Functor syntax

610

.filter(_ > 2) // MonadPlus syntax

611

.foldMap(_.toString) // Foldable syntax

612

613

val validation = (

614

"John".successNel[String] |@| // Validation syntax

615

25.successNel[String] |@| // Applicative syntax

616

"john@example.com".successNel[String]

617

) { User(_, _, _) }

618

619

val comparison = 1 === 1 && 5 > 3 // Equal and Order syntax

620

val combined = "Hello" |+| " World" // Monoid syntax

621

```