передача типов данных в функции или вызов метода - PullRequest
2 голосов
/ 09 ноября 2011

Исходя из ООП, я начал в последние недели читать о функциональном программировании и начал изучать 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)

1 Ответ

1 голос
/ 10 ноября 2011

Я чувствовал то же самое, что и вы, когда впервые начал изучать функциональное программирование - это calling functions on data types is nothing else than calling methods on immutable objects.

Я думаю, важно понимать, что это один из способов взглянуть на FP, а не единственный. С другой стороны, методология ООП, объединяющая данные и процедуры в классы, является одним из способов думать о программировании, но не единственным. Для некоторых проблем ООП приводит к отличным решениям, в то время как для других это не так хорошо.

Пример, который вы привели, или способ, которым вы решили его решить, может оказаться более подходящим для ООП, чем для ФП. Не то, чтобы вы не могли решить эту проблему с помощью FP, просто это кажется немного неловким и вынужденным - как вы заметили. Я предполагаю, что этот пример доставляет вам неприятности, потому что он имеет дело с изменением среды, что очень естественно для ООП.

Существуют и другие проблемы, для которых решение FP будет казаться естественным и простым, а версия ООП неловкой и вынужденной. Подумайте о проблемах, где решение включает преобразование входа в выход:

  • input: набор карт (то есть таблица базы данных) output: отчет, сгруппированный по одному из столбцов, отфильтрованный по предикату, с агрегированными функциями, примененными к столбцам
  • ввод: вывод текста программы: дерево разбора
  • input: вывод дерева разбора: статистика по длине функции, именам переменных, количеству комментариев и т. Д.

Подводя итог, если вы продолжите функциональное программирование, вы обнаружите, что есть другие проблемы, для которых хорошо подходит FP, и решения которых намного проще и естественнее, чем в языках OO.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...