How to collapse a match on a discriminated union in F# - selenium

How does one take the results of a function that returns object, and cast it to a discriminated union in F#?
Problem scenario, I'm working with the javascript executor on a webdriver in selenium. The docs specify that the output should be an object of the certian types or list of types. (Ref https://www.w3.org/TR/webdriver/#executing-script)
I'd like to give the returning object some structure by casting it into a discriminated union so I can match on it later.
Casting directly doesn't work and union types aren't allowed to have constructors so I can't exactly drop it in there either. What's the proper way of going about this?
type JsResult =
| E of IWebElement
| I of Int64
| B of bool
| S of String
| LE of IWebElement list
| LI of Int64 list
| LB of bool list
| LS of String list
| N of Object
override self.ToString () =
match self with
| E e -> e.Text
| I i -> i.ToString()
| B b -> b.ToString()
| S s -> s
| LE le -> String.concat " " (le |> Seq.map(fun x-> x.Text))
| LI li -> String.concat " " (li |> Seq.map(fun x-> x.ToString()))
| LB lb -> String.concat " " (lb |> Seq.map(fun x-> x.ToString()))
| LS ls -> String.concat " " ls
| N _ -> String.Empty
let execute script : JsResult = (browser :?> IJavaScriptExecutor).ExecuteScript(script) :> JsResult

Maybe create a static factory method? Try this:
type JsResult =
// ...
with static member ofObject o =
match box o with
| :? IWebElement as e -> E e
| :? Int64 as i -> I i
| :? bool as b -> B b
| :? String as s -> S s
| :? (IWebElement list) as le -> LE le
| :? (Int64 list) as li -> LI li
| :? (bool list) as lb -> LB lb
| :? (String list) as ls -> LS ls
| :? Object as n -> N o
| _ -> failwith "No wrapper available for type"
let execute script : JsResult = (browser :?> IJavaScriptExecutor).ExecuteScript(script) |> JsResult.ofObject
(The boxing is only needed if any of the specified type is a value type like int, or bool).

Related

BST using modules - OCaml

I am trying to create module/interface (i dont exactly know how its called, i am new to the language) for basic operations on BST in OCaml. My goal is to have an implementation that lets me doing something like this:
T.create();;
T.push(2);;
T.push(3);;
T.push(5);;
in order to get a bst tree consisting of 2,3,5.
But at the moment to achieve this i have to write something like this:
let teeBst = T.push(2)(T.push(3)(T.push(5)(T.create())));;
So when I am checking/using my code I have to do it like this:
let tee2 = T.push(2)(T.push(3)(T.push(5)(T.create())));;
T.postorder(tee2);;
The output is fine:
# val tee2 : T.bt = <abstr>
# - : int list = [2; 3; 5]
But, as I said before, I would like to achieve this doing as below:
T.push(2);;
T.push(3);;
T.push(5);;
T.postorder();;
(I realise this requires some changes to my postorder function but the one I am currently using is a temporary one so I can check the tree I have atm )
Below is my implementation. If you see the solution, please let me know ;)
module type Tree =
sig
type bt
val create: unit -> bt
val push: int -> bt -> bt
val find: int -> bt -> bool
val preorder: bt -> int list
val postorder: bt -> int list
val inorder: bt -> int list
end;;
module T : Tree =
struct
type bt = E | B of bt * int * bt
let create () = E
let rec push x = function
| E -> B(E, x, E)
| B (l, y, r) when x<y -> B(push x l, y, r)
| B (l, y, r) when x>y -> B(l, y, push x r)
| xs -> xs;;
let rec find x = function
| E -> false
| B(l, y,_) when x< y -> find x l
| B(_,y,r) when x>y -> find x r
| _ -> true;;
let rec preorder = function
| B(l,v,r) -> v::(preorder r) # (preorder l)
| E -> [];;
let rec inorder = function
| B(l,v,r) ->(inorder r) # v::(inorder l)
| E -> []
let rec postorder = function
| B(l,v,r) -> (postorder r) # (postorder l) # [v]
| E -> []
end;;
It seems like you want modules to be classes, but I'd advise you to consider more idiomatic solutions. Have you considered using the pipe operator?
T.create()
|> T.push(2)
|> T.push(3)
|> T.push(5)
|> T.postorder;;
Or with local open (which makes more sense if you have a module with a longer name than just T of course) you can even do
T.(
create()
|> push(2)
|> push(3)
|> push(5)
|> postorder
);
What you're asking for would require introducing global mutable state, which isn't just "some changes" but an entirely different paradigm. And one that is generally frowned upon because it makes your code unpredictable and hard to debug since it relies on state that might change at any moment from anywhere.
Another possibility is to actually use classes, since OCaml has those too. Then you'd still have mutable state, but it would at least be contained.

How can I create a function that only accepts a subset of constructors of a type?

Let's say I have a type like this:
data Foo = Bar String | Baz | Qux String
I want to have a function like this:
get : Foo -> String
get (Bar s) = s
get (Qux s) = s
As written, this compiles, but it's not total, as there are missing cases; in other words, get Baz is treated like a hole rather than as an expression that doesn't typecheck.
I want to replace that Foo in the type signature of get with something that specifies that the value must be either a Bar or a Qux. How can I express this subset of the Foo type?
You could also mix the two approaches (by Kim Stiebel and Anton Trunov) and construct a helper data type. The type OnlyBarAndQux can only be constructed with values of Bar and Qux. For idris it is then possible to automatically infer a proof if this is the case when invoking get:
module FooMe
data Foo = Bar String | Baz | Qux String
data OnlyBarAndQux: Foo -> Type where
BarEy: OnlyBarAndQux (Bar s)
QuxEx: OnlyBarAndQux (Qux s)
||| get a string from a Bar or Qux
total
get: (f: Foo) -> {auto prf : OnlyBarAndQux f} -> String
get (Bar s) {prf = BarEy} = s
get (Qux s) {prf = QuxEx} = s
-- Tests
test1: get $ Bar "hello" = "hello"
test1 = Refl
test2: get $ Qux "hello" = "hello"
test2 = Refl
-- does not compile
-- test3: get $ Baz = "hello"
I'd follow the approach taken in the std library for List head, for example. This is basically what Markus wrote plus using Dec for witnessing that a Foo being not Baz is decidable:
%default total
data Foo = Bar String | Baz | Qux String
data NotBaz : Foo -> Type where
IsBar: NotBaz(Bar z)
IsQux: NotBaz(Qux z)
Uninhabited (NotBaz Baz) where
uninhabited _ impossible
notBaz : (f : Foo) -> Dec (NotBaz f)
notBaz Baz = No absurd
notBaz (Bar s) = Yes IsBar
notBaz (Qux s) = Yes IsQux
get: (f : Foo) -> {auto ok : NotBaz f} -> String
get (Bar s) { ok = IsBar } = s
get (Qux s) { ok = IsQux } = s
s: String
s = get (Bar "bar")
Some comments about this:
Do not use just a predicate a -> Bool for working with a subset type of a; create a view like NotBaz above. See the Idris tutorial on views, this post, and this answer for context.
Use Dec whenever possible instead of equality. Intutitively, you will be able to use Dec for predicates on types for which you can explicitly decide the truth of the predicate: see notBaz above.
auto implicit arguments can help reducing the visual/cognitive clutter at usage site
There is more than one way to do this, but the easiest is probably to make Foo a type constructor that takes a parameter indicating whether it's a Foo with a String in it or not. In this example I have used a Bool as the parameter:
%default total
data Foo : Bool -> Type where
Bar : String -> Foo True -- a Foo constructed with Bar will have type Foo True
Baz : Foo False -- and a Foo constructed with Baz will have type Foo False
Qux : String -> Foo True
get : Foo True -> String
get (Bar s) = s
get (Qux s) = s
I'd go with Kim Stebel's answer (if changing Foo is an option, as observed by #Eduardo Pareja Tobes), but I'd like to show another way. You can use a subset type, which is the same thing as dependent pair:
total
get : (f ** Not (f = Baz)) -> String
get (f ** pf) with (f)
get (f ** _) | (Bar s) = s -- this is as before
get (f ** contra) | Baz = void $ contra Refl -- a contradictory case
get (f ** _) | (Qux s) = s -- this is as before
(f ** Not (f = Baz)) can be translated as "some f of type Foo, but not Baz".
To call get you need to provide a dependent pair of an element of type Foo and a proof that it is not equal to Baz, like so:
s : String
s = get (Bar "bar" ** \Refl impossible)

OCaml lexical vs dynamic scoping

I have doubts about some topics. In short I have to write an interpreter in Ocaml both static and dynamic scope.
For now I implemented a version with static scoping through the use of an environment (IDE * value) lists, and a eval (evn * exp), passing evn when a statement.
The question then, and 'can be developed both scoping (dynamic - static) with a list and a eval function like this, by making changes to the reading of the list or you have to take another way?
Here a part of code:
type ide = string
type bi_operator =
Plus
|Minus
|Mul
|Div
|Eq
|LThan
|LEq
|And
|Or
type exp =
Var of ide
|Const of value
|Fun of ide * exp
|Not of exp
|BOp of exp * bi_operator * exp
|Let of ide * exp * exp
|If of exp * exp * exp
|FunApp of exp * exp
and value =
| Int of int
| Bool of bool
| Closure of env * string * exp
and env = (ide * value) list
The evaluation code:
let rec eval (evn,e) = match e with
| Const _ -> expToV(e)
| Var x -> lookup (x,evn)
| BOp (a,b,c) -> ( match ((eval(evn,a)),(eval(evn,c))) with
| (Int a, Int c) ->
( match b with
| Plus -> Int (a + c)
| Minus -> Int (a - c)
| Mul -> Int (a * c)
| Div -> Int (a / c)
| Eq -> Bool (a = c)
| LThan -> Bool (a < c)
| LEq -> Bool (a <= c)
| _ -> raise (MLFailure "Not a valid Int operator")
)
| (Bool a, Bool c) ->
( match b with
| Eq -> Bool (a = c)
| And -> Bool (a && c)
| Or -> Bool (a || c)
| _ -> raise (MLFailure "Not a valid Bool operator")
)
| _ -> raise (MLFailure "Bin arguments do not match"))
| Fun (a,b) -> Closure (evn,a,b)
| Not (a) -> (match (eval(evn,a)) with
| (Bool a) -> if(a = false) then Bool(true) else Bool(false)
| _ -> raise (MLFailure "Bin arguments do not match"))
| Let (a,b,c) -> eval ( ((a,eval (evn,b))::evn) , c)
| If (a,b,c) -> if (eval (evn,a) = (Bool true)) then (eval (evn,b)) else (eval (evn,c))
| FunApp (a,b) -> (match eval (evn,a) with
| Closure (environment,funct,args) -> eval (((funct, eval (evn,b))::environment),args)
| _ -> raise (MLFailure "Bin arguments do not match"))
Here 's an example of me making a statement:
let _ = eval ([("x", Int 3);("t", Int 5);("z", Int 5);("x", Int 5);("y", Int 1)], (Let ("x", Const (Int 1),
Let ("f", Fun ("y", Var "x"),
Let ("x", Const (Int 2), FunApp (Var "f", Const(Int 0)))))));;
Or
let _ = eval ([], (Let ("x", Const (Int 1),
Let ("f", Fun ("y", Var "x"),
Let ("x", Const (Int 2), FunApp (Var "f", Const(Int 0)))))));;
With these examples the result is Int 1.
In my book this example gives:
Lexical : Int 1
Dynamic : Int 2
Its looks a correct
implementation.
All you need to do is replace
| Closure (environment,funct,args) -> eval ((funct, eval (evn,b))::environment,args)
with
| Closure (environment,funct,args) -> eval ((funct, eval (evn,b))::evn,args)
At that point, you can also remove the env component from Closure, because it's never used.
FWIW, I kept your variable naming in the above code, though it is really weird, given that funct is the parameter name, and args is the function body.

Unable to serialize Discriminated Union in F# Chiron

If I have:
type a = B | C
How do I write the static members ToJson and FromJson?
I know how to write it for a Record Type (which is shown in the examples at Chiron: JSON + Ducks + Monads ) but I can't find any examples for a DU.
EDIT
Following s952163 helpful answer (and follow up comment), I have adapted the code to try and work with a 'simple' DU of choice A | B (rather than A of string | B of ...). My code is now:
type SimpleDU =
| A
| B
static member ToJson (t : SimpleDU) =
match t with
| A -> Json.writeNone "a"
| B -> Json.writeNone "b"
static member FromJson (_ : SimpleDU) =
json {
let! duA = Json.tryRead "a"
match duA with
| Some s -> return s
| None -> return SimpleDU.B
}
This compiles but when I try it with the sample operation code:
let a = A
let b = B
let a2json = a |> Json.serialize
let (json2a:SimpleDU) = a2json |> Json.deserialize
let b2json = b |> Json.serialize
let (json2b:SimpleDU) = b2json |> Json.deserialize
json2a is incorrectly returning SimpleDU.B
An implementation which serializes A to Object (map [("SimpleDU", String "a")]) instead of Object (map [("a", Null null)]) is:
#I #"..\packages\Chiron.6.1.0\lib\net40"
#I #"..\packages\Aether.8.1.2\lib\net35"
#r "Chiron.dll"
#r "Aether.dll"
open Chiron
type SimpleDU =
| A
| B
static member ToJson x =
Json.write "SimpleDU" <|
match x with
| A -> "a"
| B -> "b"
static member FromJson(_ : SimpleDU) =
json {
let! du = Json.tryRead "SimpleDU"
match du with
| Some "a" -> return A
| Some "b" -> return B
| Some x -> return! Json.error <| sprintf "%s is not a SimpleDU case" x
| _ -> return! Json.error "Not a SimpleDU JSON"
}
// val serializedA : Json = Object (map [("SimpleDU", String "a")])
let serializedA = A |> Json.serialize
let serializedB = B |> Json.serialize
let (a : SimpleDU) = serializedA |> Json.deserialize
let (b : SimpleDU) = serializedB |> Json.deserialize
let aMatches = a = A
let bMatches = b = B
let serializedABBAA = [ A; B; B; A; A ] |> Json.serialize
let (abbaa : SimpleDU list) = serializedABBAA |> Json.deserialize
let abbaaMatches = abbaa = [ A; B; B; A; A ]
// allFine = true
let allFine = aMatches && bMatches && abbaaMatches
let defects =
Array [ Object <| Map.ofList [ ("SimpleDU", String "c") ]
Object <| Map.ofList [ ("Foo", String "bar") ] ]
// attempt = Choice2Of2 "Not a SimpleDU JSON"
let (attempt : Choice<SimpleDU list, string>) = defects |> Json.tryDeserialize
Instead of "a"and "b" you could use trueand false which would get rid of the Some x case, but I'd rather have readable cases in the JSON.
You can add static members to DUs as well. In Chiron Taming Types in the last paragraph there is a link mentioning that some examples with DUs should be up soon. However assuming you can't wait and that you prefer Chiron over Json.NET or FsPickler here is an example. Probably there are some other ways but I'm not familiar with Chiron's operators so I decided to use a computation expression (pilfered from Chiron Computation Expressions). The idea is that you can pattern match. So probably you can pattern match over more complicated DUs as well. If you are familiar with Chiron I'm sure it can be made more idiomatic. You can see that Chiron itself is using DUs, and for example the Json object is map.
#I #"..\packages\Chiron.6.1.0\lib\net40"
#I #"..\packages\Aether.8.0.2\lib\net35"
#I #"..\packages\FParsec.1.0.1\lib\net40-client"
#r "Chiron.dll"
#r "Aether.dll"
#r "Fparsec.dll"
open Aether
open Chiron
open Chiron.Operators
open FParsec
type SimpleDU =
|A of string
|B of int * bool
static member ToJson (x: SimpleDU) =
match x with
| A s -> Json.write "A" s
| B (i, b) -> Json.write "B" (i, b)
static member FromJson (_ : SimpleDU) =
json {
let! duA = Json.tryRead "A"
match duA with
| Some s -> return A s
| None ->
let! x = Json.read "B"
return B x
}
And here's how it works:
let a = A "Jason"
let b = B (13,true)
let a2json = a |> Json.serialize //val Json = Object (map [("A", String "Jason")])
let (json2a:SimpleDU) = a2json |> Json.deserialize //val json2a : SimpleDU = A "Jason"
let b2json = b |> Json.serialize
let (json2b:SimpleDU) = b2json |> Json.deserialize
There are some examples in the source code as well that might be useful for you:Chiron
Seems to me that https://stackoverflow.com/a/36828630/2314532 might help you. That answer points to this F# snippet defining ToString and FromString functions for discriminated unions:
open Microsoft.FSharp.Reflection
let toString (x:'a) =
match FSharpValue.GetUnionFields(x, typeof<'a>) with
| case, _ -> case.Name
let fromString<'a> (s:string) =
match FSharpType.GetUnionCases typeof<'a> |> Array.filter (fun case -> case.Name = s) with
|[|case|] -> Some(FSharpValue.MakeUnion(case,[||]) :?> 'a)
|_ -> None
You would still need to get from the string (just "A" or "B") to the full DU object (e.g., reading the rest of the DU's data in s952163's SimpleDU example), and as I haven't used Chiron yet, I can't help you much there. But that may give you a starting point.

OCaml: circularity between variant type and module definition

I'm switching from Haskell to OCaml but I'm having some problems. For instance, I need a type definition for regular expressions. I do so with:
type re = EmptySet
| EmptyWord
| Symb of char
| Star of re
| Conc of re list
| Or of (RegExpSet.t * bool) ;;
The elements inside the Or are in a set (RegExpSet), so I define it next (and also a map function):
module RegExpOrder : Set.OrderedType =
struct
let compare = Pervasives.compare
type t = re
end
module RegExpSet = Set.Make( RegExpOrder )
module RegExpMap = Map.Make( RegExpOrder )
However, when I do "ocaml [name of file]" I get:
Error: Unbound module RegExpSet
in the line of "Or" in the definition of "re".
If I swap these definitions, that is, if I write the modules definitions before the re type definitions I obviously get:
Error: Unbound type constructor re
in the line of "type t = re".
How can I solve this?
Thanks!
You can try to use recursive modules. For instance, the following compiles:
module rec M :
sig type re = EmptySet
| EmptyWord
| Symb of char
| Star of re
| Conc of re list
| Or of (RegExpSet.t * bool)
end =
struct
type re = EmptySet
| EmptyWord
| Symb of char
| Star of re
| Conc of re list
| Or of (RegExpSet.t * bool) ;;
end
and RegExpOrder : Set.OrderedType =
struct
let compare = Pervasives.compare
type t = M.re
end
and RegExpSet : (Set.S with type elt = M.re) = Set.Make( RegExpOrder )