如何在F#中检索元组的头部和尾部?
例如Conj (a, b),头部是Conj,尾部是(a, b).
我想buildtree在每个参数上递归运行函数,把头作为Node元素,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)
Run Code Online (Sandbox Code Playgroud)更新后:
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"))
Run Code Online (Sandbox Code Playgroud)
正如Ankur所说,你不能得到一个元组的头和尾 - 这些操作是为处理具有任意长度的函数列表而设计的,并且无法定义在编译时具有已知长度的元组.如果你想要任意长度的数据,你应该使用元组和模式匹配(或List.head和List.tail).
如果您确实需要动态处理元组,可以使用F#反射:
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
Run Code Online (Sandbox Code Playgroud)
但请注意,反射通常有点慢,只应在需要时使用(即编写一些动态且无法以其他方式编写的代码).
| 归档时间: |
|
| 查看次数: |
1424 次 |
| 最近记录: |