Я пытаюсь реализовать счетчик и хочу преобразовать что-то типа State Int в Int, чтобы добавить его в переменную. Может ли кто-нибудь помочь мне разработать вспомогательную функцию для выполнения этого приведения?
Я уже давно застрял на этом, потому что не очень привык работать с состоянием монады.
Название State a немного вводит в заблуждение, имхо, State a не указывает систему в определенном состоянии, оно описывает изменение состояния, поэтому вам нужно сначала перевести систему в какое-то начальное состояние.
Я сильно подозреваю, что вы не хотите делать то, что, как вы говорите, хотите делать. Действительно, вы почти наверняка хотите прямо противоположного: вместо того, чтобы извлекать Int из вашего State Int _, вам, вероятно, следует подумать о том, как преобразовать функцию, которая потребляет текущий счетчик из Int -> _ в State Int Int -> _ (которая затем может быть применена к get :: State Int Int ). В зависимости от типа возвращаемого значения этой функции вы можете посмотреть fmap или (>>=).





Используйте execState, чтобы запустить действие с сохранением состояния и получить окончательное состояние:
execState :: State s a -> s -> s
Например, incByOne увеличивает счетчик на единицу:
incByOne :: State Int ()
incByOne = modify (+1)
Затем, если вы используете монадный бегун execState с начальным состоянием 7:
main :: IO ()
main = do
let initialCount = 7
let count = execState incByOne initialCount
print count
Он будет напечатан 8
Моя проблема в том, как мне объединить ее со строкой. Например, как мне сделать «a»++ (показать счетчик)?
Как только у вас есть count, как вы говорите: "a" ++ show count
Название State немного вводит в заблуждение: это не состояние определенной системы: по сути, State s a — это функция, которая принимает состояние (типа s) и создает новое (возможно, другое) состояние и выходное значение (типа a). Затем вы можете объединить два таких State s a и State s b, где вы сначала меняете состояние первого, а затем передаете его следующему.
Но важно то, что State s a не содержит состояния: сначала вам нужно установить исходное состояние. Например 0, с:
execState myState0Но если вы сделаете это несколько раз, вы каждый раз получите один и тот же ответ, поскольку вы помещаете одно и то же начальное состояние и поскольку недетерминированности нет, каждый раз это будет давать один и тот же результат.
Скорее всего, execState на самом деле не то, что вы ищете: State Int — это не какая-то «волшебная база данных», охватывающая несколько запусков этой State, это база данных, пока вы оцениваете поток State s a элементов.
Запустите его, например.
evalState. Или вы просто ищете обозначения>>=иdo? В любом случае,State Int— это не тип, у него есть видType -> Type.