Can anyone explain *what is lenses` in terms of OCaml?
I tried to google it, but almost all of them are in Haskell's world.
Just wish some simple demonstrations for it in OCaml's world, like what it is, what it can be used for, etc.
A lens is a pair of functions (getter and setter) that are under a data-structure. It's really that simple. There is currently a library for them,
type ('s,'a) t =
{ get : 's -> 'a;
set : 'a -> 's -> 's; }
An example (using the ocaml library listed above) for a tailor,
type measurements = { inseam : float; }
type person = { name : string; measurements : measurements; }
let lens_person_measurements =
{ get = (fun x -> x.measurements);
set = (fun a x -> {x with measurements = a}); }
let lens_measurements_inseam =
{ get = (fun x -> x.inseam);
set = (fun a x -> {x with inseam = a}); }
let lens_person_inseam =
compose lens_measurements_inseam lens_person_measurements
When composing the lenses together, you can see it as a way to avoid having to write with constantly when dealing with records. You can also see that a ppx to create these lenses would be very helpful. Yaron recently posted on the caml-list they are working on something that would be similar to lens.
An important insight in the van Laarhoven Lens definition(PDF) shows how one function (fmap) of a particular Functor can do these operations (set and get and very helpfully an update function).
Related
I am C# dev that has just starting to learn F# and I have a few questions about unit testing. Let's say I want to the following code:
let input () = Console.In.ReadLine()
type MyType= {Name:string; Coordinate:Coordinate}
let readMyType =
input().Split(';')
|> fun x -> {Name=x.[1]; Coordinate = {
Longitude = float(x.[4].Replace(",","."))
Latitude =float(x.[5].Replace(",","."))
}}
As you can notice, there are a few points to take in consideration:
readMyType is calling input() with has a side effect.
readMyType assume many thing on the string read (contains ';' at least 6 columns, some columns are float with ',')
I think the way of doing this would be to:
inject the input() func as parameter
try to test what we are getting (pattern matching?)
Using NUnit as explained here
To be honest I'm just struggling to find an example that is showing me this, in order to learn the syntax and other best practices in F#. So if you could show me the path that would be very great.
Thanks in advance.
First, your function is not really a function. It's a value. The distinction between functions and values is syntactic: if you have any parameters, you're a function; otherwise - you're a value. The consequence of this distinction is very important in presence of side effects: values are computed only once, during initialization, and then never change, while functions are executed every time you call them.
For your specific example, this means that the following program:
let main _ =
readMyType
readMyType
readMyType
0
will ask the user for only one input, not three. Because readMyType is a value, it gets initialized once, at program start, and any subsequent reference to it just gets the pre-computed value, but doesn't execute the code over again.
Second, - yes, you're right: in order to test this function, you'd need to inject the input function as a parameter:
let readMyType (input: unit -> string) =
input().Split(';')
|> fun x -> {Name=x.[1]; Coordinate = {
Longitude = float(x.[4].Replace(",","."))
Latitude =float(x.[5].Replace(",","."))
}}
and then have the tests supply different inputs and check different outcomes:
let [<Test>] ``Successfully parses correctly formatted string``() =
let input() = "foo;the_name;bar;baz;1,23;4,56"
let result = readMyType input
result |> should equal { Name = "the_name"; Coordinate = { Longitude = 1.23; Latitude = 4.56 } }
let [<Test>] ``Fails when the string does not have enough parts``() =
let input() = "foo"
(fun () -> readMyType input) |> shouldFail
// etc.
Put these tests in a separate project, add reference to your main project, then add test runner to your build script.
UPDATE
From your comments, I got the impression that you were seeking not only to test the function as it is (which follows from your original question), but also asking for advice on improving the function itself, so as to make it more safe and usable.
Yes, it is definitely better to check error conditions within the function, and return appropriate result. Unlike C#, however, it is usually better to avoid exceptions as control flow mechanism. Exceptions are for exceptional situations. For such situations that you would have never expected. That is why they are exceptions. But since the whole point of your function is parsing input, it stands to reason that invalid input is one of the normal conditions for it.
In F#, instead of throwing exceptions, you would usually return a result that indicates whether the operation was successful. For your function, the following type seems appropriate:
type ErrorMessage = string
type ParseResult = Success of MyType | Error of ErrorMessage
And then modify the function accordingly:
let parseMyType (input: string) =
let parts = input.Split [|';'|]
if parts.Length < 6
then
Error "Not enough parts"
else
Success
{ Name = parts.[0]
Coordinate = { Longitude = float(parts.[4].Replace(',','.')
Latitude = float(parts.[5].Replace(',','.') }
}
This function will return us either MyType wrapped in Success or an error message wrapped in Error, and we can check this in tests:
let [<Test>] ``Successfully parses correctly formatted string``() =
let input() = "foo;the_name;bar;baz;1,23;4,56"
let result = readMyType input
result |> should equal (Success { Name = "the_name"; Coordinate = { Longitude = 1.23; Latitude = 4.56 } })
let [<Test>] ``Fails when the string does not have enough parts``() =
let input() = "foo"
let result = readMyType input
result |> should equal (Error "Not enough parts)
Note that, even though the code now checks for enough parts in the string, there are still other possible error conditions: for example, parts.[4] may be not a valid number.
I am not going to expand on this further, as that will make the answer way too long. I will only stop to mention two points:
Unlike C#, verifying all error conditions does not have to end up as a pyramid of doom. Validations can be nicely combined in a linear-looking way (see example below).
The F# 4.1 standard library already provides a type similar to ParseResult above, named Result<'t, 'e>.
For more on this approach, check out this wonderful post (and don't forget to explore all links from it, especially the video).
And here, I will leave you with an example of what your function could look like with full validation of everything (keep in mind though that this is not the cleanest version still):
let parseFloat (s: string) =
match System.Double.TryParse (s.Replace(',','.')) with
| true, x -> Ok x
| false, _ -> Error ("Not a number: " + s)
let split n (s:string) =
let parts = s.Split [|';'|]
if parts.Length < n then Error "Not enough parts"
else Ok parts
let parseMyType input =
input |> split 6 |> Result.bind (fun parts ->
parseFloat parts.[4] |> Result.bind (fun lgt ->
parseFloat parts.[5] |> Result.bind (fun lat ->
Ok { Name = parts.[1]; Coordinate = { Longitude = lgt; Latitude = lat } } )))
Usage:
> parseMyType "foo;name;bar;baz;1,23;4,56"
val it : Result<MyType,string> = Ok {Name = "name";
Coordinate = {Longitude = 1.23;
Latitude = 4.56;};}
> parseMyType "foo"
val it : Result<MyType,string> = Error "Not enough parts"
> parseMyType "foo;name;bar;baz;badnumber;4,56"
val it : Result<MyType,string> = Error "Not a number: badnumber"
This is a little follow-up to the excellent answer of #FyodorSoikin trying to explore the suggestion
keep in mind though that this is not the cleanest version still
Making the ParseResult generic
type ParseResult<'a> = Success of 'a | Error of ErrorMessage
type ResultType = ParseResult<Defibrillator> // see the Test Cases
we can define a builder
type Builder() =
member x.Bind(r :ParseResult<'a>, func : ('a -> ParseResult<'b>)) =
match r with
| Success m -> func m
| Error w -> Error w
member x.Return(value) = Success value
let builder = Builder()
so we get a concise notation:
let parse input =
builder {
let! parts = input |> split 6
let! lgt = parts.[4] |> parseFloat
let! lat = parts.[5] |> parseFloat
return { Name = parts.[1]; Coordinate = { Longitude = lgt; Latitude = lat } }
}
Test Cases
Tests are always fundamental
let [<Test>] ``3. Successfully parses correctly formatted string``() =
let input = "foo;the_name;bar;baz;1,23;4,56"
let result = parse input
result |> should equal (ResultType.Success { Name = "the_name"; Coordinate = { Longitude = 1.23; Latitude = 4.56 } })
let [<Test>] ``3. Fails when the string does not have enough parts``() =
let input = "foo"
let result = parse input
result |> should equal (ResultType.Error "Not enough parts")
let [<Test>] ``3. Fails when the string does not contain a number``() =
let input = "foo;name;bar;baz;badnumber;4,56"
let result = parse input
result |> should equal (ResultType.Error "Not a number: badnumber")
Notice the usage of a specific ParseResult from the generic one.
minor note
Double.TryParse is just enough in the following
let parseFloat (s: string) =
match Double.TryParse s with
| true, x -> Success x
| false, _ -> Error ("Not a number: " + s)
I am a beginner to ML/Haskell and I am trying to create a list of structures.
Actually, I am developing a web application in Urweb (functional web programming language, a lot of features from ML and Haskell.) I am trying to create an interface to Tinymce (open source rich text editor, and it consists of all the plugin such as print, link). So to manage all plugins, I am composing in the form of structure and I need one data structure to hold all the structures (Plugins in my case) and at the end stage in can be used to initialize my editor.
For example:
val plugins = [print, link, img];
and elements inside list plugins such as print is a structure:
structure print = struct
type t = string
.
.
end
How can I achieve this?
The general answer is that No you cannot create a list of
structures, the same is true as well of signatures, and functors
however; if your plugin system is built in a way in which the entry types, and exit types of each plugin are the same across all plugins, you can build a kind of closure to a structure and embed that into a function.
you can then use functors, to build up the functions of your plugin system
We start out with the interface of each "plugin".
signature DANCER =
sig
type t;
val dancer : t
val tired : t -> bool
val dance : t -> t;
end
Followed by the interface through which our application interacts with the plugin.
datatype exhaustion = Exhausted;
signature DANCING_MANIA =
sig
val dance : unit -> exhaustion;
end
The implementation of the above DANCING_MANIA signature,
accepts a DANCER, and hides the differences between plugins/structures
functor Dancer (D : DANCER) : DANCING_MANIA =
struct
fun dance() =
let fun until_exhaustion (dancer) =
if not (D.tired dancer)
then until_exhaustion(D.dance(dancer))
else Exhausted;
in until_exhaustion(D.dancer) end
end
Finally we can implement some plugins, and throw them in a list.
structure Tony :> DANCER =
struct
type t = int;
val dancer = 5;
fun tired x = x <= 0;
fun dance x = (print "tony dance!\n"; x - 1);
end
structure Annette :> DANCER =
struct
type t = real;
val dancer = 1.0;
fun tired x = x <= 0.0;
fun dance x = (print "annette dance!\n"; x - 0.2);
end
structure TonyDance = Dancer(Tony);
structure AnnetteDance = Dancer(Annette);
val dancers = [TonyDance.dance, AnnetteDance.dance];
fun danceOff (x::xs) = let val _ = x(); in danceOff(xs) end
| danceOff ([]) = ();
val _ = danceOff(dancers);
So, the idea is that while you cannot create a list of structures,
you can create a list of things, that each contain a different structure,
as long as the exposed types are uniform.
I am trying to stick heterogeneous types in a list making use of flexible types
type IFilter<'a> =
abstract member Filter: 'a -> 'a
type Cap<'a when 'a: comparison> (cap) =
interface IFilter<'a> with
member this.Filter x =
if x < cap
then x
else cap
type Floor<'a when 'a: comparison> (floor) =
interface IFilter<'a> with
member this.Filter x =
if x > floor
then x
else floor
type Calculator<'a, 'b when 'b:> IFilter<'a>> (aFilter: 'b, operation: 'a -> 'a) =
member this.Calculate x =
let y = x |> operation
aFilter.Filter y
type TowerControl<'a> () =
let mutable calculationStack = List.empty
member this.addCalculation (x: Calculator<'a, #IFilter<'a>> ) =
let newList = x::calculationStack
calculationStack <- newList
let floor10 = Floor<int> 10
let calc1 = Calculator<int, Floor<int>> (floor10, ((+) 10))
let cap10 = Cap 10
let calc2 = Calculator (cap10, ((-) 5))
let tower = TowerControl<int> ()
tower.addCalculation calc1
tower.addCalculation calc2
In the example above
member this.addCalculation (x: Calculator<'a, #IFiler<'a>> ) =
produces the error
error FS0670: This code is not sufficiently generic. The type variable 'a could not be generalized because it would escape its scope.
Apologies if a similar question has already been posted.
Thank you.
There's no easy way to do this. It looks like you really want calculationStack to have type:
(∃('t:>IFilter<'a>).Calculator<'a, 't>) list
but F# doesn't provide existential types. You can use the "double-negation encoding" ∃'t.f<'t> = ∀'x.(∀'t.f<'t>->'x)->'x to come up with the following workaround:
// helper type representing ∀'t.Calculator<'t>->'x
type AnyCalc<'x,'a> = abstract Apply<'t when 't :> IFilter<'a>> : Calculator<'a,'t> -> 'x
// type representing ∃('t:>IFilter<'a>).Calculator<'a, 't>
type ExCalc<'a> = abstract Apply : AnyCalc<'x,'a> -> 'x
// packs a particular Calculator<'a,'t> into an ExCalc<'a>
let pack f = { new ExCalc<'a> with member this.Apply(i) = i.Apply f }
// all packing and unpacking hidden here
type TowerControl<'a> () =
let mutable calculationStack = List.empty
// note: type inferred correctly!
member this.addCalculation x =
let newList = (pack x)::calculationStack
calculationStack <- newList
// added this to show how to unpack the calculations for application
member this.SequenceCalculations (v:'a) =
calculationStack |> List.fold (fun v i -> i.Apply { new AnyCalc<_,_> with member this.Apply c = c.Calculate v }) v
// the remaining code is untouched
let floor10 = Floor<int> 10
let calc1 = Calculator<int, Floor<int>> (floor10, ((+) 10))
let cap10 = Cap 10
let calc2 = Calculator (cap10, ((-) 5))
let tower = TowerControl<int> ()
tower.addCalculation calc1
tower.addCalculation calc2
This has the big advantage that it works without modifying the Calculator<_,_> type, and that the semantics are exactly what you want, but the following disadvantages:
It's hard to follow if you're unfamiliar with this way of encoding existentials.
Even if you are familiar, there's a lot of ugly boilerplate (the two helper types) since F# doesn't allow anonymous universal qualification either. That is, even given that F# doesn't directly support existential types, it would be much easier to read if you could write something like:
type ExCalc<'a> = ∀'x.(∀('t:>IFilter<'a>).Calculator<'a,'t>->'x)->'x
let pack (c:Calculator<'a,'t>) : ExCalc<'a> = fun f -> f c
type TowerControl<'a>() =
...
member this.SequenceCalcualtions (v:'a) =
calculationStack |> List.fold (fun v i -> i (fun c -> c.Calculate v)) v
But instead we've got to come up with names for both helper types and their single methods. This ends up making the code hard to follow, even for someone already familiar with the general technique.
On the off chance that you own the Calculator<_,_> class, there's a much simpler solution that might work (it may also depend on the signatures of the methods of the real Calcuator<,> class, if it's more complex than what you've presented here): introduce an ICalculator<'a> interface, have Calculator<_,_> implement that, and make calculationStack a list of values of that interface type. This will be much more straightforward and easier for people to understand, but is only possible if you own Calculator<_,_> (or if there's already an existing interface you can piggy back on). You can even make the interface private, so that only your code is aware of its existence. Here's how that would look:
type private ICalculator<'a> = abstract Calculate : 'a -> 'a
type Calculator<'a, 'b when 'b:> IFilter<'a>> (aFilter: 'b, operation: 'a -> 'a) =
member this.Calculate x =
let y = x |> operation
aFilter.Filter y
interface ICalculator<'a> with
member this.Calculate x = this.Calculate x
type TowerControl<'a> () =
let mutable calculationStack = List.empty
member this.addCalculation (x: Calculator<'a, #IFilter<'a>> ) =
let newList = (x :> ICalculator<'a>)::calculationStack
calculationStack <- newList
member this.SequenceCalculations (v:'a) =
calculationStack |> List.fold (fun v c -> c.Calculate v) v
Rust has a linear type system. Is there any (good) way to simulate this in OCaml? E.g., when using ocaml-lua, I want to make sure some functions are called only when Lua is in a specific state (table on top of stack, etc).
Edit: Here's a recent paper about resource polymorphism relevant to the question: https://arxiv.org/abs/1803.02796
Edit 2: There are also a number of articles about session types in OCaml available, including syntax extensions to provide some syntactic sugar.
As suggested by John Rivers, you can use a monadic style to represent
"effectful" computation in a way that hides the linear constraint in
the effect API. Below is one example where a type ('a, 'st) t is
used to represent computation using a file handle (whose identity is
implicit/unspoken to guarantee that it cannot be duplicated), will
product a result of type 'a and leave the file handle in the state
'st (a phantom type being either "open" or "close"). You have to use
the run of the monad¹ to actually do anything, and its type ensure
that the file handles are correctly closed after use.
module File : sig
type ('a, 'st) t
type open_st = Open
type close_st = Close
val bind : ('a, 's1) t -> ('a -> ('b, 's2) t) -> ('b, 's2) t
val open_ : string -> (unit, open_st) t
val read : (string, open_st) t
val close : (unit, close_st) t
val run : ('a, close_st) t -> 'a
end = struct
type ('a, 'st) t = unit -> 'a
type open_st = Open
type close_st = Close
let run m = m ()
let bind m f = fun () ->
let x = run m in
run (f x)
let close = fun () ->
print_endline "[lib] close"
let read = fun () ->
let result = "toto" in
print_endline ("[lib] read " ^ result);
result
let open_ path = fun () ->
print_endline ("[lib] open " ^ path)
end
let test =
let open File in
let (>>=) = bind in
run begin
open_ "/tmp/foo" >>= fun () ->
read >>= fun content ->
print_endline ("[user] read " ^ content);
close
end
(* starting with OCaml 4.13, you can use binding operators:
( let* ) instead of ( >>= ) *)
let test =
let open File in
let ( let* ) = bind in
run begin
let* () = open_ "/tmp/foo" in
let* content = read in
print_endline ("[user] read " ^ content);
close
end
Of course, this is only meant to give you a taste of the style of
API. For more serious uses, see Oleg's monadic
regions examples.
You may also be interested in the research programming language
Mezzo, which aims to
be a variant of ML with finer-grained control of state (and related
effectful patterns) through a linear typing discipline with separated
resources. Note that it is only a research experiment for now, not
actually aimed at users. ATS is also relevant,
though finally less ML-like. Rust may actually be a reasonable
"practical" counterpart to these experiments.
¹: it is actually not a monad because it has no return/unit combinator, but the point is to force type-controlled sequencing as the monadic bind operator does. It could have a map, though.
I have defined a type like that:
type s_program =
{ globals : s_var list;
main: s_block; }
and s_var =
{ s_var_name: string;
s_var_type: s_type;
s_var_uniqueId: s_uniqueId }
and s_uniqueId = int
At a point of my program, i have a variable p: s_program, but I need to change s_var_uniqueId of every element of p.globals, for instance, add 1 to every s_var_uniqueId. I have some questions:
1) May I modify directly the related values in p, or do I have to assign new values to a new p':s_program
2) May I write something like that:
let p' =
{ p with
globals = List.map (fun var -> { var with s_var_uniqueId = var.s_var_uniqueId + 1 }) p.globals
Thank you very much.
Edit 1: correct with part as suggested
First you may want to read this section on record in OCaml and this chapter on modifiable data structures. As stated, you will see that records are not mutable. Second, you need to think about what you really want : mutable record, record with mutable fields or mutable record with mutable fields. For example suppose that we have a record for complex numbers (this is the same example in ref 1).
type complex = { re:float; im:float } ;;
If you declare something like
let c = {re=2.;im=3.} ;;
then you cannot change neither c nor re (or im). Indeed c := {re=4.;im=6.} ;; or c.re := 4.;; will both failed with an error. To get a mutable record, you just have to use a reference for c.
let c = ref {re=2.;im=3.} ;;
Then you can change c with c := {re=4.;im=6.} ;;. But I think that you want to have mutable field ! Then you have to precise which fields are mutables. Suppose that you want all fields to be mutable you can write
type complex = { re:float ref; im:float ref }
let make_complex r i = { re = ref r ; im = ref i }
let c = make_complex 3. 4.
;;
and then change fields with
c.re := 6. ; c.im := 7. ;;
It would be easier with a function of type float -> float -> ()
let change_re c r = c.re := r ;;
let change_im c i = c.im := i ;;
let change_complex c r i = change_re c r ; change_im c i ;;
However, I will suggest you to really think about bringing imperative feature like this in your code. This could be a simple way to completly wreck its readibility.
1) That depends whether you want to use Ocaml as an imperative or functional programming language :). If it's the former, you can make both fields of the records mutable (by adding mutable keyword before field name) and then change them in place. However I'd strongly advice not to do that and to:
2) go with your second approach, which looks perfectly fine (except that you seem to be missing {...} for the second record modification.