Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Functional programming 我在f-sharp中有一个相互递归问题_Functional Programming_F# - Fatal编程技术网

Functional programming 我在f-sharp中有一个相互递归问题

Functional programming 我在f-sharp中有一个相互递归问题,functional-programming,f#,Functional Programming,F#,我在F#中有以下类型: 我的任务是创建一个函数:find:Name->FamilyTree->returns(查找姓名、性别、年份,[所有子女的姓名列表] 我知道它与相互递归有关,但我不确定如何应用它。 这是我到目前为止写的: let fstn (f:FamilyTree) = match f with |P(n,s,y,c) -> n let rec find n t = function |P(n1,s1,y1,cs) -> if n1=n then (

我在F#中有以下类型:

我的任务是创建一个函数:find:Name->FamilyTree->returns(查找姓名、性别、年份,[所有子女的姓名列表]

我知道它与相互递归有关,但我不确定如何应用它。 这是我到目前为止写的:

let fstn (f:FamilyTree) =
    match f with
    |P(n,s,y,c) -> n

let rec find n t = function
    |P(n1,s1,y1,cs) -> if n1=n then (n1,s1,y1,List.map (fun x -> fstn x) cs) 
                           else findC n cs
and findC n clist =
    match clist with
    |[] -> []
    |c::cs -> if n = fstn c then find n c 
                            else findC n cs
当我跑的时候

find "May" f1;;
我得到:

error FS0001: This expression was expected to have type
    'Name * Sex * YearOfBirth * Name list'
but here has type
    ''a list'

有人知道我做错了什么吗?我知道类型有问题,但我不知道如何解决。我可以利用我能得到的所有帮助,非常感谢!

以下解决方案在Visual Studio Pro 2019版本16.8.3中运行

// addressing: https://stackoverflow.com/questions/65307389/i-have-a-mutual-recursion-problem-in-f-sharp

open System

type Name = string
type Sex = 
    | M // male
    | F // female
type YearOfBirth = int;;
type FamilyTree = 
    | Person of Name * Sex * YearOfBirth * Children
    | Nothing 
and 
    Children = FamilyTree list

//here is an example:
let family_example = [Person("Larry",M,1920,
                        [Person("May",F,1945,
                            [Person("Fred",M,1970,[])]);
                             Person("Joe",M,1950,
                                [Person("Adam",M,1970,[])]);
                             Person("Paul",M,1955,[])
                             ]
                         )]

let rec find name ( familyTree_list : FamilyTree list) : FamilyTree =
    match familyTree_list with
    | (Person( try_name, _, _, _)::_) & (person::_) when name = try_name -> person 
    | (Person( _, _, _, children)::siblings) when (children <> [] || siblings <> []) ->
        let depth_search_result = find name children
        if Nothing <> depth_search_result then depth_search_result
        else find name siblings
    | _ -> Nothing

[<EntryPoint>]
let main argv =
    printfn "%A" (find "May" family_example)
    printfn "%A" (find "Joe" family_example)
    printfn "%A" (find "no one" family_example)
    0 // return an integer exit code
//寻址:https://stackoverflow.com/questions/65307389/i-have-a-mutual-recursion-problem-in-f-sharp
开放系统
类型名称=字符串
类型性别=
|M//男
|女
出生年份类型=int;;
类型FamilyTree=
|姓名*性别*出生年份*子女的人
|没什么
及
Children=家庭树列表
//以下是一个例子:
让家庭为例=[个人(“拉里”,M,1920,
[个人(“五月”),1945年5月6日,
[个人(“弗雷德”,M,1970,[]);
人(“乔”,男,1950年,
[个人(“亚当”,M,1970,[])];
个人(“保罗”,M,1955,[])
]
)]
让rec查找姓名(familyTree\u列表:familyTree列表):familyTree=
将familyTree\u列表与
|(当name=try\u name->Person时,Person(try\u name,u,u,u,u,u)::u)和(Person::u)
|(人(,,,,,孩子)::兄弟姐妹)当(孩子[]| |兄弟姐妹[])->
让深度搜索结果=查找名称子项
如果没有深度搜索结果,则深度搜索结果
否则会找到兄弟姐妹的名字
|什么都没有
[]
让主argv=
printfn“%A”(查找“May”系列\u示例)
printfn“%A”(查找“Joe”族\u示例)
printfn“%A”(查找“无人”族\u示例)
0//返回整数退出代码
变量名和类型名是可读的,但与您的版本基本相同。不需要函数
fstn
findC
f1
变成了
family\u示例
,并为可读性重新格式化

您可以从branch
StackOverflow\u 001\u I\u f-sharp中存在相互递归\u问题\u取下此解决方案的git回购


如果您还有任何问题,请告诉我。

如果您键入annotate所有函数,则很容易找到它。从函数开始,find需要两个参数,但实现只需要一个(FamilyTree).一般提示:为递归类型提供一个伴随选项通常会有所帮助。在您的代码中,预变形可以轻松地将当前节点的名称与请求匹配,并返回一个选项,该选项将向父节点发出停止搜索的信号。
// addressing: https://stackoverflow.com/questions/65307389/i-have-a-mutual-recursion-problem-in-f-sharp

open System

type Name = string
type Sex = 
    | M // male
    | F // female
type YearOfBirth = int;;
type FamilyTree = 
    | Person of Name * Sex * YearOfBirth * Children
    | Nothing 
and 
    Children = FamilyTree list

//here is an example:
let family_example = [Person("Larry",M,1920,
                        [Person("May",F,1945,
                            [Person("Fred",M,1970,[])]);
                             Person("Joe",M,1950,
                                [Person("Adam",M,1970,[])]);
                             Person("Paul",M,1955,[])
                             ]
                         )]

let rec find name ( familyTree_list : FamilyTree list) : FamilyTree =
    match familyTree_list with
    | (Person( try_name, _, _, _)::_) & (person::_) when name = try_name -> person 
    | (Person( _, _, _, children)::siblings) when (children <> [] || siblings <> []) ->
        let depth_search_result = find name children
        if Nothing <> depth_search_result then depth_search_result
        else find name siblings
    | _ -> Nothing

[<EntryPoint>]
let main argv =
    printfn "%A" (find "May" family_example)
    printfn "%A" (find "Joe" family_example)
    printfn "%A" (find "no one" family_example)
    0 // return an integer exit code