From 226182cb8a2934d6247d793d04d3dae8fb871d03 Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Mon, 18 May 2026 04:58:31 +0100 Subject: [PATCH] =?UTF-8?q?fix(stdlib):=20option.affine=20=E2=80=94=20last?= =?UTF-8?q?=20STAGE-A=20file;=2019/19=20(#128)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - take/get_or_insert: Rust-style `&mut Option` -> AffineScript `mut opt: Option` ownership-prefix param (grammar has no `&mut`) - drop prelude `map` from the import (option defines its own Option `map`; prelude's is the list map — name conflict, same class as collections#191) - transpose/map_filter: rewrite the list-map with the file's own for-loop ++ idiom instead of the (shadowed) map - cat_options: Unit statement-block match arm so it matches the `None => {}` arm (a bare assignment expr is typed as its RHS -> Array vs Unit across arms; collect already works via its Never arm) - collect/cat_options: reassigned `values` -> `let mut` stdlib 18->19/19 — STAGE A coherence complete. 233/233 dune test, zero regression. Refs #128 Co-Authored-By: Claude Opus 4.7 (1M context) --- stdlib/option.affine | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/stdlib/option.affine b/stdlib/option.affine index 042a9608..ed7a2405 100644 --- a/stdlib/option.affine +++ b/stdlib/option.affine @@ -6,7 +6,10 @@ module option; // `Option`/`Result` types + constructors are owned by `prelude` (ADR-011). -use prelude::{Option, Some, None, Result, Ok, Err, map}; +// `map` is defined locally below as the Option map (f, Option); +// it is NOT imported from prelude (prelude's `map` is the list map +// with a different signature — importing both would conflict). +use prelude::{Option, Some, None, Result, Ok, Err}; // This module is the single canonical home for the Option *operations* // (is_some/is_none/unwrap/unwrap_or/map/filter/contains/…). #133 removed @@ -184,14 +187,20 @@ fn unzip(opt: Option<(A, B)>) -> (Option, Option) { /// Transpose Option of list to list of Option fn transpose(opt: Option<[T]>) -> [Option] { match opt { - Some(list) => map(fn(x) => Some(x), list), + Some(list) => { + let mut result = []; + for x in list { + result = result ++ [Some(x)]; + } + result + }, None => [] } } /// Collect list of Options into Option of list (None on any None) fn collect(opts: [Option]) -> Option<[T]> { - let values = []; + let mut values = []; for opt in opts { match opt { Some(value) => values = values ++ [value], @@ -203,10 +212,13 @@ fn collect(opts: [Option]) -> Option<[T]> { /// Filter out Nones from list fn cat_options(opts: [Option]) -> [T] { - let values = []; + let mut values = []; for opt in opts { match opt { - Some(value) => values = values ++ [value], + // Statement-block arm so the arm is Unit-typed and matches the + // `None => {}` arm (a bare assignment expression is typed as its + // RHS, which would clash Array vs Unit across the arms). + Some(value) => { values = values ++ [value]; }, None => {} } } @@ -215,7 +227,10 @@ fn cat_options(opts: [Option]) -> [T] { /// Map list with function returning Option, filtering Nones fn map_filter(f: T -> Option, list: [T]) -> [U] { - let results = map(f, list); + let mut results = []; + for x in list { + results = results ++ [f(x)]; + } cat_options(results) } @@ -317,14 +332,14 @@ fn replace_none(opt: Option, replacement: Option) -> Option { } /// Take value from Option, leaving None -fn take(opt: &mut Option) -> Option { +fn take(mut opt: Option) -> Option { let result = opt; opt = None; result } /// Insert value into Option if None -fn get_or_insert(opt: &mut Option, value: T) -> T { +fn get_or_insert(mut opt: Option, value: T) -> T { match opt { Some(x) => x, None => {