Когда я читал документацию SDL
в haskell, я обнаружил, что некоторые функции неизбежно изменяют его вход. Например, blitSurface
имеет поверхность назначения как входную, но обновляется внутри функции. Теперь, обобщая проблему, если у меня есть функция f :: a -> IO a
, она нарушает состав, если я изменяю a
внутри функции? Что насчет f :: IO a -> IO a
? Что насчет a -> IO()
? А как насчет IO a -> IO()
?Разбивает ли он композицию для изменения ввода в Haskell?
Учитывая, что blitSurface
на самом деле является чужой функцией, а создание новой поверхности каждого кадра не очень эффективно, эти функции трудно избежать. Будут ли такие функции вызывать проблемы в более широких масштабах? Например, с помощью fModifySurface :: Surface -> IO()
, который делает разрушительное обновление в качестве примера:
main = do
w <- ... -- The window surface
-- Do something here
s <- someFuncGetSurface -- We get a surface here
fModifySurface s -- Destructively update s
blitSurface ...... -- Ignore the actual API, but destructively updates w
Существует ли какая-либо неожиданная семантика в коде выше? Если да, то каков наилучший способ использовать внешние функции, которые меняют ввод?
Строго говоря, это не «функции». –
ОК, «функции» в императивном смысле. –
Пока все внешние функции возвращают 'IO SomeType', фундаментальное свойство не должно быть нарушено. Ваш случай сильно отличается от того, что вы звоните, например. 'writeIORef' для обновления изменяемой переменной? Последний «безопасен», даже если его можно злоупотреблять, чтобы написать унииоматический код. – chi