Skip to content

Instantly share code, notes, and snippets.

@LeeeeT
Created February 25, 2024 12:34
Show Gist options
  • Save LeeeeT/1bf218a20111d95baa1754ed34e687e7 to your computer and use it in GitHub Desktop.
Save LeeeeT/1bf218a20111d95baa1754ed34e687e7 to your computer and use it in GitHub Desktop.
Pure IO
import sys
from collections.abc import Callable, Iterator
from functools import cache
type Lazy[T] = Callable[[], T]
def run_lazy[T](lazy: Lazy[T]) -> T:
return lazy()
type Stream[T] = Lazy[tuple[T, Stream[T]]]
def iterator_to_stream[T](iterator: Iterator[T]) -> Stream[T]:
return cache(lambda: (next(iterator), iterator_to_stream(iterator)))
type State[S, T] = Callable[[S], tuple[T, S]]
def state_identity[S, T](value: T) -> State[S, T]:
def state(s: S) -> tuple[T, S]:
return value, s
return state
state_return = state_pure = state_identity
def state_map[S, From, To](state: State[S, From], function: Callable[[From], To]) -> State[S, To]:
def new_state(s: S) -> tuple[To, S]:
value, s = state(s)
return function(value), s
return new_state
def state_join[S, T](state: State[S, State[S, T]]) -> State[S, T]:
def new_state(s: S) -> tuple[T, S]:
value, s = state(s)
return value(s)
return new_state
def state_bind[S, From, To](state: State[S, From], function: Callable[[From], State[S, To]]) -> State[S, To]:
return state_join(state_map(state, function))
type Stdin = Stream[str]
stdin = iterator_to_stream(sys.stdin)
type Input[T] = State[Stdin, T]
line: Input[str] = run_lazy
main: Input[str] = (
state_bind(line, lambda a:
state_bind(line, lambda b:
state_return(a + b)
))
)
sys.stdout.write(main(stdin)[0])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment