package lens

  1. Overview
  2. Docs
Functional lenses

Install

Dune Dependency

Authors

Maintainers

Sources

v1.2.4.tar.gz
sha256=ec2205a1f5a9087026b7906f40ced312a0ec9d66deff6c95ea0388c88960240e
md5=563750d717d0ec581e91f2c537ca0b26

Description

Based on F# implementation in https://github.com/fsharp/fsharpx see https://github.com/fsharp/fsharpx/blob/master/src/FSharpx.Extras/Lens.fs for the original implementation see http://bugsquash.blogspot.com/2011/11/lenses-in-f.html - Lenses in F# see http://stackoverflow.com/questions/8179485/updating-nested-immutable-data-structures - Stackoverflow question about Updating nested immutable data structures see http://stackoverflow.com/questions/5767129/lenses-fclabels-data-accessor-which-library-for-structure-access-and-mutatio - Haskell libraries for structure access and mutation see http://www.youtube.com/watch?v=efv0SQNde5Q - Functional lenses for Scala by Edward Kmett on YouTube see http://patternsinfp.wordpress.com/2011/01/31/lenses-are-the-coalgebras-for-the-costate-comonad - Lenses are the coalgebras for the costate comonad by Jeremy Gibbons

Published: 31 Jul 2020

README

Functional Lenses

This package provides some basic types and functions for using lenses in OCaml. Functional lenses are based on F# implementation in FSharpX. See src/FSharpx.Extras/Lens.fs for the original implementation. Written by Alessandro Strada.

See also:

Examples

First load Lens in utop.

utop # #use "lens.ml";;

Given a couple of records

    type car = {
        make : string;
        model: string;
        mileage: int;
      };;

    type editor = {
        name: string;
        salary: int;
        car: car;
    };;

    type book = {
        name: string;
        author: string;
        editor: editor;
    };;

Create a new nested record

    let scifi_novel = {
       name =  "Metro 2033";
       author = "Dmitry Glukhovsky";
       editor =  {
         name = "Vitali Gubarev";
         salary =  1300;
         car =  {
           make = "Lada";
           model = "VAZ-2103";
           mileage = 310000
        }
      }
    };;

Now to construct a few lenses to access some things

    let car_lens = {
        get = (fun x -> x.car);
        set = (fun v x -> { x with car = v })
      };;

    let editor_lens = {
        get = (fun x -> x.editor);
        set = (fun v x -> { x with editor = v })
    };;

    let mileage_lens = {
        get = (fun x -> x.mileage);
        set = (fun v x -> { x with mileage = v })

    };;

Using these lenses we can modify the mileage without having to unpack the record

    let a = compose mileage_lens (compose car_lens editor_lens) in
    _set 10 scifi_novel a;;

Or using the Infix module we can do the same thing, only shorter.

    _set 10 scifi_novel (editor_lens |-- car_lens |-- mileage_lens);;

    (* or *)

    ((editor_lens |-- car_lens |-- mileage_lens) ^= 10) @@ scifi_novel;;

Ppx syntax extension

Lenses can be generated using the 'lens.ppx_deriving' plugin for ppx_deriving

#require "lens.ppx_deriving";;

type car = {
  make : string;
  model: string;
  mileage: int;
} [@@deriving lens];;

val car_make: (car, string) Lens.t
val car_model: (car, string) Lens.t
val car_mileage: (car, int) Lens.t

The prefix option can be used to prefix each lens name with lens.

#require "lens.ppx_deriving";;

type car = {
  make : string;
  model: string;
  mileage: int;
} [@@deriving lens { prefix = true }];;

val lens_car_make: (car, string) Lens.t
val lens_car_model: (car, string) Lens.t
val lens_car_mileage: (car, int) Lens.t

The submodule option groups all the lenses in a sub-module Lens.

#require "lens.ppx_deriving";;

type car = {
  make : string;
  model: string;
  mileage: int;
} [@@deriving lens { submodule = true }];;

module Lens :
  val make : (car, string) Lens.t
  val model : (car, string) Lens.t
  val mileage : (car, int) Lens.t
end

When the prefix and submodule options are combined, this is the module name which is prefixed.

#require "lens.ppx_deriving";;

type car = {
  make : string;
  model: string;
  mileage: int;
} [@@deriving lens { submodule = true; prefix = true }];;

module CarLens :
  val make : (car, string) Lens.t
  val model : (car, string) Lens.t
  val mileage : (car, int) Lens.t
end

Dependencies (5)

  1. dune >= "1.0"
  2. ppxfind build
  3. ppx_tools build
  4. ppx_deriving < "5.0"
  5. ocaml >= "4.10"

Dev Dependencies (1)

  1. ounit with-test

Used by

None

Conflicts

None

OCaml

Innovation. Community. Security.