-
How do I retrieve the head and tail of a tuple in F#?
For example
Conj (a, b), the head isConj, tail is(a, b). -
I want to recursively run
buildtreefunction on each parameters, put the head asNode‘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?
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:
And if you want to make it work for n-tuples you’ll have to define one overload for each n: