Я определенно был бы признателен за информацию о лучших способах сделать это или дополнительную информацию о том, как это работает с объективами (я до сих пор не очень понимаю, что это делает).
Я попробую. Это будет беглое объяснение не только для простоты, но и потому, что я все еще осваиваю объектив. Прежде чем начать, обратите внимание, что вы ссылаетесь на документацию Chart 0.14, версию до преобразования API в lens. Вот текущие документы, к которым вам следует обратиться. Теперь к вашему фрагменту:
layout_y_axis . laxis_generate .~ scaledAxis def (0,1)
Это функция, которая применяется к вашему макету. В нем layout_y_axis
и laxis_generate
- линзы. Объективы являются ссылками; в данном случае ссылки на поля в типах данных. В простых случаях использования линзы очень похожи на полевые ярлыки, за исключением того, что, в отличие от звукозаписывающих лейблов, они первоклассные, и с ними можно делать много интересных вещей. На самом деле линзы — это функции, которые можно составить из (.)
; однако композиция выполняется слева направо, в отличие от обычной практики Haskell. Таким образом, в:
layout_y_axis . laxis_generate
layout_y_axis
— это ссылка на поле в макете, laxis_generate
— это ссылка на поле на оси («функция, которая генерирует данные оси», согласно документам); их составление (в обратном/OO порядке) дает ссылку на производящую функцию оси Y макета.
Помимо самих линз, другой ключевой частью вашего фрагмента является (.~)
, один из многих линзы операторы. Он производит функции установки; то есть он принимает ссылку и значение и создает функцию, которая устанавливает цель ссылки. В вашем случае вы получаете функцию, которая делает scaledAxis def (0,1)
функцией генерации оси Y макета.
Теперь, если вы посмотрите документацию Graphics. Rendering.Chart.Layout вы найдете не только линзы, но также _layout_y_axis
и _laxis_generate
, которые являются полями Layout
и LayoutAxis
соответственно. Это задние поля линз; на самом деле линзы могут быть созданы и в данном случае автоматически генерируются из них. Учитывая, что модуль экспортирует метки полей, вы можете написать свою функцию без линз, используя только синтаксис записи:
\lay -> lay
{ _layout_y_axis =
(\yax -> yax { _laxis_generate = scaledAxis def (0,1) })
$ _layout_y_axis lay
}
Однако это слишком некрасиво. lens может сделать намного больше, чем улучшить неприятный синтаксис; в любом случае, для таких библиотек, как Chart
, в которых манипуляции с полями выполняются по всему API, простая замена обычного синтаксиса вложенных записей на что-то аккуратное и компонуемое уже очень хорошо.
Примечание. В модуле «Простой» на Диаграмме 1.9 используйте .=
вместо .~
:
import qualified Graphics.Rendering.Chart.Backend.Cairo as C
import qualified Graphics.Rendering.Chart.Easy as C
plotit outfile points =
C.toFile C.def outfile $ do
C.layout_y_axis . C.laxis_generate C..= C.scaledAxis C.def (0, 1)
C.plot (C.points "n_coffees" points) -- etc.
person
duplode
schedule
02.04.2014
$ layout_y_axis ∘ laxis_generate .~ scaledAxis def (0,1)
к функции макета, я мог бы заставить ось находиться в диапазоне значений от 0 до 1. Я был бы определенно признателен за информацию о лучших способах сделать это или дополнительную информацию о том, как это работает с линзами (до сих пор не очень понимаю, что это делает). - person Craig   schedule 02.04.2014