52700.fb2 Учебник по Haskell - читать онлайн бесплатно полную версию книги . Страница 126

Учебник по Haskell - читать онлайн бесплатно полную версию книги . Страница 126

проблема: что должна возвращать функция write?

Для того чтобы упорядочить эти вычисления мы воспользуемся типом State. Каждое выражение будет

принимать фиктивное состояние и возвращать его. Тогда функция fun запишется так:

fun :: Int -> State s Int

fun arg = State $ \s0 ->

let (mem, s1)

= runState (new arg)

s0

((),

s2)

= runState (write mem arg)

s1

(x,

s3)

= runState (read mem)

s2

y

= x + 1

((),

s4)

= runState (write mem y)

s3

(z,

s5)

= runState (read mem)

s4

in (z, s5)

new

:: a -> State s (Mem a)

write

:: Mem a -> a -> State s ()

read

:: Mem a -> State s a

Тип Mem параметризован типом значения, которое хранится в памяти. В этом варианте мы не можем

изменить порядок следования выражений, поскольку нам приходится передовать состояние. Мы могли бы

записать это выражение гораздо короче с помощью методов класса Monad, но мне хотелось подчеркнуть как

передача состояния навязывает порядок вычисления. Функция write теперь возвращает пустой кортеж. Но

порядок не теряется за счёт состояния. Пустой кортеж намекает на то, что единственное назначение функции

write – это обновление состояния.

Однако этого не достаточно. Мы хотим, чтобы обновление значения было скрыто от пользователя в чистой

функции. Мы хотим, чтобы тип функции fun не содержал типа State. Для этого нам откуда-то нужно взять

начальное значение состояния. Мы можем решить эту проблему, зафиксировав тип s. Пусть это будет тип

FakeState, скрытый от пользователя.

module Mutable(

Mutable, Mem, purge,

new, read, write)

where

newtype Mutable a = Mutable (State FakeState a)

data FakeState = FakeState

purge :: Mutable a -> a