(no subject)

Oct 06, 2006 14:33

Хороший человек vbayda показал, как он использует boost::bind:

if (entityes_.end() == std::find_if(entityes_.begin(), entityes_.end(),
boost::bind < bool > (&intersect < double >, c,
boost::bind(&world::positions::entity::shape_,
boost::bind(&world::entity::positions_, _1)
)
)
))
Как на меня, мягко выражаясь, выглядит не слишком читабельно.
Понял слова Алана Перлиса "избыток синтаксического сахара приводит к раку фигурных скобок" (переврал цитату, и ну его).
Не слишком-то C++ пригоден для функциональщины. Правда, синтаксис получился не намного хуже, чем у Lisp-а.

Попытался переписать это на Haskell. Не могу скомпилировать, хоть ты тресни. Хотя выглядит немного лучше.
Комментирую синтаксис "в стиле учебника" для тех, кто не знает языка.

module Main
where

-- это описание типа данных - "записи" с конструктором и одним полем
data Entity = CreateEntity { position :: Position }

data Position = CreatePosition { circle :: Circle }

data Circle = CreateCircle { x, y, r :: Float }

-- указание типа функции (аргументов и параметров).
-- Обычно можно опустить, type inferrance его определяет.
circlesIntersect :: Circle -> Circle -> Bool
-- это собственно описание функции: имя, параметры, =, тело-выражение
circlesIntersect c1 c2 = sqr (r c1 + r c2) < sqr (x c1 - x c2) + sqr (y c1 - y c2)
where sqr x = x*x

findIntersecting :: Circle -> [Entity] -> Entity
findIntersecting circle entities =
-- это тот самый байнд одного (первого) параметра. Выглядит так: (имя функции) параметр.
find ((entityMatches) circle) entities
where
entityMatches :: Circle -> Entity -> Bool
entityMatches c e = circlesIntersect c (circle position e)
-- Оказывается, в Haskell обращение к полям структуры выглядит не как c.x, а как x(c).
-- Или x c, что в этом случае то же самое.

main = putStr "Hello\n"
Итого получается (получилось бы, если бы я лучше понимал синтаксис и типизацию)

findIntersecting circle entities =
find ((entityMatches) circle) entities where
entityMatches c e = circlesIntersect c (circle position e)
или, без промежуточной "объясняющей" функции

findIntersecting circle entities =
find (((circlesIntersect) c (circle position e)) circle) entities
Считаем скобки, почти как в Лиспе. Кстати, синтаксис Лиспа должен был быть похож на хаскельный. Но его где-то там не смогли заимплементить и бросили нынешнем виде, который предназначался только для списковых данных.

haskell, Профессиональное, cpp

Previous post Next post
Up