Исходя из ООП, я начал в последние недели читать о функциональном программировании и начал изучать Haskell. Очень часто я читал, что (чистые) функции проще тестировать, поскольку нет сложных процедур настройки и демонтажа. Это звучит разумно, и я был согласен. Составление этих функций позволяет мне создавать более сложные функции с очень хорошо протестированной «базой».
Когда я смотрел, как писать свои первые программы, некоторые функции получали все больше параметров, и поэтому я начал создавать новые типы данных, которые для меня похожи на структуры. Конечно, типы данных связывают то, что логически принадлежит друг другу, и иногда состоят из других типов данных.
Вызов функций, таких как
MyTpye = foo(MyTpye, someParam)
похоже на выполнение ООП с очень уродливым синтаксисом, как во времена C с указателями на функции в структурах:
MyType = foo(this, someParam) = {
...
return modified_copy_of_this;
}
Тестирование этих функций также требует, чтобы я сначала настроил мой новый тип данных, что может быть сложно, и я просто чувствую, что выигрываю мало.
Полагаю, я все еще слишком ограничен и сосредоточен на ООП-способе написания кода. У меня просто такое ощущение, что вызов функций для типов данных - это не что иное, как вызов методов для неизменяемых объектов (конечно, каждый установщик должен был бы вернуть измененную версию объекта).
Может кто-нибудь объяснить мне это немного?
Большое спасибо!
Я добавил этот пример на Haskell. Это мои первые шаги, и я постарался не публиковать такой ужасный код.
Это только первые части алгоритма обучения реформированию. Настройка «среды» с доступными состояниями, действиями и функцией вознаграждения.
type Action = [Double]
type State = [Double]
data StateSet = StateSet [State] deriving (Show)
data ActionSet = ActionSet [Action] deriving (Show)
data Environment = Environment {
availableStates :: StateSet,
availableActions:: ActionSet,
currentState :: State,
rewardfnc :: State -> Action -> Double,
lastReward :: Double
}
rewardFunction :: State -> Action -> Double
rewardFunction s a = (-1)
doAction :: Environment -> Action -> Environment
doAction env a = Environment (availableStates env) (availableActions env) a (rewardfnc env) ((rewardfnc env) (currentState env) a)
getReward :: Environment -> Double
getReward env = (lastReward env)
states = StateSet [[i,j] | i <- [1..10], j <- [1..10]]
actions = ActionSet [[i,j] | i <- [1..10], j <- [1..10]]
initEnv = Environment states actions [0,0] rewardFunction 0.0
env = doAction initEnv [2,2]
reward = getReward(env)