Let say I have DU of three types and a function which accepts this DU as a parameter:
type A = decimal<p>
type B = decimal<p>
type C = decimal<p>
type ABC = A of A | B of B | C of C
let myfunc (val: ABC) =
match val with
| A v -> ...
| B v -> ...
| C v -> ...
Is there a better way to define a function which accepts DU of only A and B without defining new type explicity?
This is a working example:
type AB = A2 of A | B2 of B
let myfunc2 (val: AB) =
match val with
| A2 v -> ...
| B2 v -> ...
This is how I would like it to be:
let myfunc2 (val: A|B) =
match val with
| A v -> ...
| B v -> ...
The language feature you're asking for is open variants, which exists in OCaml, but not in F#. For instance,
type ABC = A of int | B of int | C of int
type AB = A of int | B of int
let myfunc (x: AB) = ...
is legal in OCaml. This can also be achieved with type-erased DUs (vote for it here!).
DU cases in F# are not actual types, but the base type (ABC) with a tag denoting which union case it is. And since there are no types which exist separately, it follows that they cannot be used as a type constraint.
You can however try and work around this with Choice. The idea is to build single case DUs and then combine them with Choice<T1, T2...>.
type A = A of int
type B = B of int
type C = C of int
type ABC = Choice<A, B, C>
type AB = Choice<A, B>
let matchAb (x: AB) =
match x with
| Choice1Of2 (A a) -> a
| Choice2Of2 (B b) -> b
Related
I implemented a Discriminated Union type that would be used to select a function:
type BooleanCombinator =
| All
| Some
| None
| AtLeast of int
| MoreThan of int
| NotMoreThan of int
| LessThan of int
| ExactlyOne
| ExactlyTwo
| AllButOne
| AllButTwo
let boolToInt (b: bool) : int = if b then 1 else 0
let combineBooleans (combinator : BooleanCombinator)
(bools : bool list)
: bool =
let n = List.sumBy boolToInt bools
match combinator with
| BooleanCombinator.All -> List.forall id bools
| BooleanCombinator.Some -> bools |> List.exists id
| BooleanCombinator.None -> bools |> List.exists id |> not
| BooleanCombinator.AtLeast i -> n >= i
| BooleanCombinator.MoreThan i -> n > i
| BooleanCombinator.NotMoreThan i -> n <= i
| BooleanCombinator.LessThan i -> n < i
| BooleanCombinator.ExactlyOne -> n = 1
| BooleanCombinator.ExactlyTwo -> n = 2
| BooleanCombinator.AllButOne -> n = bools.Length - 1
| BooleanCombinator.AllButTwo -> n = bools.Length - 2
This looked Ok to me but the compiler started to look at all instances of Some and None as belonging to this DU, instead of the Option DU.
I do not want to go through all of my code replacing Some with Option.Some and None with Option.None.
Is there a way to tell the compiler that unqualified Some and None are actually Option.Some and Option.None?
Or should I just give different names to these DU cases, like AtLeastOne and ExactlyZero
The general rule for resolving name collisions in F# is "last declaration wins". Because your custom DU is declared after Option, its constructors Some and None win over those of Option.
But this rule offers a way to fix the problem: you just need to "reassert" the declarations after your custom DU:
type Bogus = Some of int | None
let g = function Some _ -> 42 | None -> 5
let x = Some 42
let inline Some a = Option.Some a
let inline None<'a> = Option.None : 'a option
let (|Some|None|) = function | Option.Some a -> Some a | Option.None -> None
let f = function Some _ -> 42 | None -> 5
let y = Some 42
If you inspect the types of g, x, f, and y in the above code:
> g
g : Bogus -> int
> f
f : 'a option -> int
> x
Bogus
> y
int option
The function g and value x were inferred to have type Bogus -> int and Bogus respectively, because Some and None in their bodies refer to Bogus.Some and Bogus.None.
The function f and value y were inferred to have Option-related types, because Some and None in their bodies refer to the Some function and the (|Some|None|) active pattern that I defined just above.
Of course, this is a rather hacky way to restore status quo. This will convince the compiler, but humans will still have a hard time reading your code. I suggest you rename the cases of your DU instead.
You can mark your DU with [<RequireQualifiedAccess>] attribute.
This means that you will be required to qualify the case name with the type whenever you use it in the code - which is something you do now anyway in your match expression.
That way an unqualified Some would still be resolved to mean Option.Some, despite the fact that you reuse the name.
It's a useful technique to know when you want to use a snappy name for a DU case - like None, Yes, Failure etc. - that by itself would be ambiguous or confusing to the reader (or the compiler, for that matter).
I am writing a simple expressions parser in F# and for each operator I want only to support a certain number of operands (e.g. two for Modulo, three for If). Here is what I have:
type Operator =
| Modulo
| Equals
| If
let processOperator operands operator =
match operator with
| Modulo ->
match operands with
| [ a:string; b:string ] -> (Convert.ToInt32(a) % Convert.ToInt32(b)).ToString()
| _ -> failwith "wrong number of operands"
| Equals ->
match operands with
| [ a; b ] -> (a = b).ToString()
| _ -> failwith "wrong operands"
| If ->
match operands with
| [ a; b; c ] -> (if Convert.ToBoolean(a) then b else c).ToString()
| _ -> failwith "wrong operands"
I would like to get rid of or simplify the inner list matches. What is the best way to accomplish this? Should I use multiple guards ?
open System
type Operator =
| Modulo
| Equals
| If
let processOperator operands operator =
match (operator, operands) with
| Modulo, [a: string; b] -> string ((int a) % (int b))
| Equals, [a; b] -> string (a = b)
| If, [a; b; c] -> if Convert.ToBoolean(a) then b else c
| _ -> failwith "wrong number of operands"
But I would suggest to move this logic of the operands to the parser, this way you get a clean operator expression, which is more idiomatic and straight forward to process, at the end you'll have something like this:
open System
type Operator =
| Modulo of int * int
| Equals of int * int
| If of bool * string * string
let processOperator = function
| Modulo (a, b) -> string (a % b)
| Equals (a, b) -> string (a = b)
| If (a, b, c) -> if a then b else c
Fold in the operands matching:
let processOperator operands operator =
match operator, operands with
| Modulo, [a; b] -> (Convert.ToInt32(a) % Convert.ToInt32(b)).ToString()
| Equals, [a; b] -> (a = b).ToString()
| If, [ a; b; c ] -> (if Convert.ToBoolean(a) then b else c).ToString()
| _ -> failwith "wrong number of operands"
Better yet, if you can, change the datatype to the following.
type Operator =
| Modulo of string * string
| Equals of string * string
| If of string * string * string
Then in the match, you can no longer fail.
In F# is it possible to have a discriminated union based on both a type and a value?
Here's an attempt at expressing this without knowing what the syntax should look like.
type Foo =
| A of int * Foo
| B of string where B.name = "1" * Foo
| C of string where C.name = "2" * Foo
| Empty
I'm not entirely sure what you're trying to achieve. But, if you want to create a type that will have a name property when which is "1" when the type is B and "2" when it is C, then you can add a member:
type Foo =
| A of int * Foo
| B of Foo
| C of Foo
| Empty
member x.Name =
match x with
| B _ -> "1"
| C _ -> "2"
| _ -> failwith "Name is not available!"
If you were hoping to use the numbers in pattern matching, then you can define an active pattern. Say you have a type with just A or B (which has a name):
type Foo =
| A of int
| B of string * Foo
Now you can write an active pattern that lets you distinguish between A, B with name "1" and B with name "2":
let (|A|B1|B2|) x =
match x with
| A n -> A n
| B("1", foo) -> B1 foo
| B("2", foo) -> B1 foo
| _ -> failwith "Invalid B"
If you now have a value foo, you can pattern match against these three cases:
match foo with
| A n -> ...
| B1 subfoo -> ...
| B2 subfoo -> ...
I have a Discriminated Union, and I hope to use built in operators like > < compare max for it.
[<CustomComparison>]
type SymbolType =
| A
| B
| C
| D
interface IComparable<SymbolType> with
member x.CompareTo y =
match x, y with
| A, A-> 0
| A, _ -> 1
| _, A-> -1
| _, _ -> 0
I understand I can use IComparable, but then i have to do a null check, what's worse is that I have to cast it like (SymbolType) y which I assume would be time consuming.
You can already use standard comparison operators on the type. The built-in implementation uses the order of declarations of the individual cases, so:
type SymbolType = A | B | C | D
// Behavior of built-in comparison
A < B = true
D <= C = false
max B D = D
This looks very fragile, so maybe it is not the best thing to rely on. If you have cases that do not contain other values, you can use enum instead of discriminated union and define the ordering you wish:
type SymbolType =
| A = 1
| B = 2
| C = 4
| D = 3
// The order is now defined by your code
SymbolType.C < SymbolType.D = false
You can just implement the required methods with thin wrappers:
[<CustomComparison>]
[<CustomEquality>]
type SymbolType =
| A
| B
| C
| D
override x.Equals y =
match y with
| :? SymbolType as t -> (((x :> IComparable<_>).CompareTo) t)=0
| _ -> false
interface IComparable with
member x.CompareTo y =
match y with
| :? SymbolType as t -> ((x :> IComparable<_>).CompareTo) t
| _ -> failwith "bad comparison"
interface IComparable<SymbolType> with
member x.CompareTo y =
match x, y with
| A, A-> 0
| A, _ -> 1
| _, A-> -1
| _, _ -> 0
This way does avoid any duplicate typing.
On CLR, operators are static functions, so you can't define them in an interface. But boxing can also be avoided if your use the interface as a constraint of type parameter of a generic function.
int Compare<T>(T lhs, T rhs) where T : IComparable<T>
{
return lhs.CompareTo(rhs) // no boxing
}
Sorry, I'm not familiar with F#, so I wrote the example in C#.
How do I retrieve the head and tail of a tuple in F#?
For example Conj (a, b), the head is Conj, tail is (a, b).
I want to recursively run buildtree function on each parameters, put the head as Node's element, where is the map in F#?
let rec getparams = map List.head (List.tail getparams);
type Elem = Prop
type Tree = E | T of Elem * Tree * Tree
let rec buildtree vars = function
| E = head vars
| T = buildtree (getparams vars)
After updated:
open System
open Microsoft.FSharp.Reflection
// Learn more about F# at http://fsharp.net
//type Prop = {a: string; b: string}
//let Prop a b = (a, b)
type Op = Prop
type tree = E | T of Op * tree * tree
let tree x y z = (x, y, z)
type binOp = Conj | Disj | Impl
type expr =
| Prop of string
| BinOp of binOp * expr * expr
| Conj of expr * expr
| Disj of expr * expr
| Impl of expr * expr
type Prop = {a: string}
let Prop a = (a)
//type Conj = {a : Prop; b : Prop}
let Conj a b = (a, b)
//type Conj_Int = {a : Prop; b : Prop}
let Conj_Int a b = Conj a b
//type Conj_Elmin1 = {a : Conj}
let Conj_Elmin1 a = fst a
//type Conj_Elmin2 = {a : Conj}
let Conj_Elmin2 a = snd a
//type Impl = {a : Prop; b : Prop}
let Impl a b = (a b)
//type Impl_Int = {assume : Prop; b : Prop}
let Impl_Int assume b = Impl assume b
//type Impl_Elmin = {a :string; b : Impl}
let Impl_Elmin a b = if a = fst b then snd b
type Neg = {a : Prop;}
let Neg a = (a)
//type Double_Neg_Int = {a : Prop;}
let Double_Neg_Int a = Neg(Neg(a))
//type Double_Neg_Elmin = {a : Prop}
let Double_Neg_Elmin a = fst(fst(a))
//type Disj = {a : Prop; b : Prop}
let Disj a b = (a,b)
//type Disj_Int1 = {a : Prop; b : Prop}
let Disj_Int1 a b = (a b)
//type Disj_Int2 = {a : Prop; b : Prop}
let Disj_Int2 a b = (a b)
//type Disj_Elmin1 = {a : Disj}
let Disj_Elmin1 a = fst(a)
//type Disj_Elmin2 = {a : Disj}
let Disj_Elmin2 a = snd(a)
type TupleSplitter = static member splitTuple (a,b,c) = (a,(b,c))
let tupleToList t = if Microsoft.FSharp.Reflection.FSharpType.IsTuple(t.GetType()) then Some (Microsoft.FSharp.Reflection.FSharpValue.GetTupleFields t |> Array.toList) else None
let operation x = List.head(List.ofSeq(FSharpValue.GetTupleFields(x)))
let parameters x = List.tail(List.ofSeq(FSharpValue.GetTupleFields(x)))
let rec map f = function | Prop _ as t -> f t | BinOp(op, a, b) -> f(BinOp(op, map f a, map f b))
(*
let rec map f = function
| Prop _ as t -> f t | Conj(a, b) -> f(Conj(map f a, map f b))
| Disj(a, b) -> f(Disj(map f a, map f b))
| Impl(a, b) -> f(Impl(map f a, map f b))
*)
let buildtree vars expr = map (function Prop v -> Map.find v vars | expr -> expr) expr
let t = buildtree(Conj("a","b"))
how to have two type of expression Op*Tree*Tree and Op*Tree?
As Ankur said, you can't get head and tail of a tuple - these operations are designed for processing functional lists that have arbitrary length and cannot be define for tuples that have a length known at compile time. If you want data with arbitrary length, you should probably use tuples and pattern matching (or List.head and List.tail).
If you really need to process tuples dynamically, you can use F# reflection:
open Microsoft.FSharp.Reflection
(1,2,3)
|> FSharpValue.GetTupleFields // Get fields of tuple as an array
|> List.ofSeq // Convert array to a list
|> List.tail // Now you can process list using head/tail
However, note that reflection is generally a bit slow and it should only be used when you need it (i.e. when writing some code that is dynamic and can't be written in any other way).
You seem to be trying to replicate Haskell syntax and semantics in F#. Don't do that. Look at existing ML code and learn how to solve your problem idiomatically. In other words, your question is an XY problem: you're asking the wrong question.
Without knowing what problem you are trying to solve, it is difficult to answer your question but my best guess is:
type Expr =
| Prop of string
| Conj of Expr * Expr
| Disj of Expr * Expr
| Impl of Expr * Expr
let deConj = function
| Conj(a, b) -> a, b
| _ -> invalidArg "expr" "deConj"
Perhaps you want to write a map over your expr type:
let rec map f = function
| Prop _ as t -> f t
| Conj(a, b) -> f(Conj(map f a, map f b))
| Disj(a, b) -> f(Disj(map f a, map f b))
| Impl(a, b) -> f(Impl(map f a, map f b))
Another solution is to rewrite your type to factor out the operators:
type binOp = Conj | Disj | Impl
type expr =
| Prop of string
| BinOp of binOp * expr * expr
let rec map f = function
| Prop _ as t -> f t
| BinOp(op, a, b) -> f(BinOp(op, map f a, map f b))
EDIT
I am not sure what your buildtree function is supposed to do but if it is evaluating expressions then perhaps you want something like this:
let buildtree vars expr =
map (function Proj v -> Map.find v vars | expr -> expr) expr
This will map one expression to another, replacing Proj v with the corresponding expression (i.e. value of the variable v) given by vars.
A tuple is defined as (exp1,exp2, ... ,expn) for example (1,"2",'3').
I can't see this pattern in your code.
If you use (exp1 exp2) it means function application (apply exp2 as first argument to function exp1).
The error you see on your code is because you defined Conj as a function accepting a function as first paramenter and you passed a string ("a") instead of a function.
If your question is how to split a tuple in head and tail you can go for the dynamic approach Tomas just explained, it will work for any n-tuple but you'll lose type information.
Otherwise the strong type solution is simply based on pattern matching:
let splitTuple (a,b,c) = (a,(b,c))
// Usage
let (head,tail) = splitTuple (1,"2",'3')
And if you want to make it work for n-tuples you'll have to define one overload for each n:
type TupleSplitter =
static member splitTuple (a,b,c) = (a,(b,c))
static member splitTuple (a,b,c,d) = (a,(b,c,d))
static member splitTuple (a,b,c,d,e) = (a,(b,c,d,e))
// ... more overloads, as much as you need
// Usage
let (head,tail) = TupleSplitter.splitTuple (1,"2",'3',4.0)
// val tail : string * char * float = ("2", '3', 4.0)
// val head : int = 1