Несколько быстрых предложений:
let pict = Pictures . (map Line) . (map $ map $ mkPt) . blocks $ pes
in do displayInWindow "My Window" (200, 200) (10, 10) white pict
У вас есть некоторые лишние вещи, которые можно удалить сразу:
let pict = Pictures . map Line . (map $ map mkPt) . blocks $ pes
in do displayInWindow "My Window" (200, 200) (10, 10) white pict
Вы все равно не избегаете скобок с map (map mkPt)
term, так что избавьтесь от $
:
let pict = Pictures . map Line . map (map mkPt) . blocks $ pes
in do displayInWindow "My Window" (200, 200) (10, 10) white pict
Вы можете написать цепочку композиции в несколько строк для ясности:
let pict = Pictures
. map Line
. map (map mkPt)
. blocks $ pes
in do displayInWindow "My Window" (200, 200) (10, 10) white pict
Блок do
излишен, потому чтооно имеет только одно утверждение, и вы можете переместить окончательное приложение за пределы определения:
let displayPict = displayInWindow "My Window" (200, 200) (10, 10) white
. Pictures
. map Line
. map (map mkPt)
. blocks
in displayPict pes
Вы можете объединить два map
s:
let displayPict = displayInWindow "My Window" (200, 200) (10, 10) white
. Pictures
. map (Line . map mkPt)
. blocks
in displayPict pes
Иногда это также более читабельнодля длинных цепочек использовать оператор обратной композиции из Control.Arrow
:
let displayPict = blocks
>>> map (Line . map mkPt)
>>> Pictures
>>> displayInWindow "My Window" (200, 200) (10, 10) white
in displayPict pes
Но все это необязательно;Приправьте ваш код по вкусу.
Что касается эффективности, я не вижу причин полагать, что эти два будут отличаться, как только оптимизатор GHC завершит работу с кодом.