unOp op = do
	(dt, inp, ft, out) <- get
	case op of
		Inc -> put (modFocus (+1) dt, inp, ft, out)
		Dec -> put (modFocus (\x -> x-1) dt, inp, ft, out)
		Left -> put (l dt, inp, ft, out)
		Right -> put (r dt, inp, ft, out)
		ReadChar -> doReadChar (dt, inp, ft, out)
		WriteChar -> put (dt, inp, ft, out ++ [writeChar $ focus dt])
		WriteInt -> put (dt, inp, ft, out ++ writeInt (focus dt))
	(_, _, _, out') <- get
	return out'
	where
		doReadChar (_, [], _, _) = return ()
		doReadChar (dt, i:is, ft, out) = put (modFocus (const $ readChar i) dt, is, ft, out)

runOp op = do
	(dt, inp, ft, out) <- get
	case op of
		Inc -> put (modFocus (+1) dt, inp, ft, out)
		Dec -> put (modFocus (\x -> x-1) dt, inp, ft, out)
		Left -> put (l dt, inp, ft, out)
		Right -> put (r dt, inp, ft, out)
		ReadChar -> doReadChar (dt, inp, ft, out)
		WriteChar -> put (dt, inp, ft, out ++ [writeChar $ focus dt])
		WriteInt -> put (dt, inp, ft, out ++ writeInt (focus dt))
	(_, _, _, out') <- get
	return out'
	where
		doReadChar (_, [], _, _) = return ()
		doReadChar (dt, i:is, ft, out) = put (modFocus (const $ readChar i) dt, is, ft, out)
runOp op = do
	(dt, inp, ft, out) <- get
	case op of
		Inc -> put (modFocus (+1) dt, inp, ft, out)
		Dec -> put (modFocus (\x -> x-1) dt, inp, ft, out)
		Left -> put (l dt, inp, ft, out)
		Right -> put (r dt, inp, ft, out)
		ReadChar -> doReadChar (dt, inp, ft, out)
		WriteChar -> put (dt, inp, ft, out ++ [writeChar $ focus dt])
		WriteInt -> put (dt, inp, ft, out ++ writeInt (focus dt))
	(_, _, _, out') <- get
	return out'
	where
		doReadChar (_, [], _, _) = return ()
		doReadChar (dt, i:is, ft, out) = put (modFocus (const $ readChar i) dt, is, ft, out)