F# 函数作为匹配函数中的参数
F# a function as an argument in a match function
我制作了一个函数,它接受一个列表和一个列表列表,return一个新的列表列表。
let rec calculator list SS =
match (List.item(0) SS) with
|[] -> []
|_ -> match (validate list (List.item(0) SS)) with
|(validate theCode list) -> List.append [(List.item(0) SS)] (calculator list (SS.[1..]))
|_ -> (calculator list (SS.[1..]))
validate 是 return 两个元组整数的函数。示例 (1,1)
list 是一个包含四个整数的列表
SS 是一个包含四个整数的列表列表
theCode 是一个包含四个整数的列表
我收到错误 "The pattern discriminator 'validate' is not defined."
也许这是一个愚蠢的问题,但 none 我越是不知道它的答案。
是否不允许在匹配表达式中使用函数作为参数。还是这里发生了完全不同的事情?
据我所知,这两个验证函数将 return 两个元组整数,因此应该能够与之匹配。
如果你的问题是如何让它编译,那么你只需要一个小的改变——函数调用本身不是一个模式,所以你需要绑定到一个值并使用 when
guard:
let rec calculator list SS =
match (List.item(0) SS) with
| [] -> []
| _ ->
match (validate list (List.item(0) SS)) with
// vvvvvvvvvv
| x when x = (validate theCode list) ->
List.append [(List.item(0) SS)] (calculator list (SS.[1..]))
| _ -> (calculator list (SS.[1..]))
但是,如果您的问题确实是“首选方法是什么”,那么虽然这对于本网站 (IMO) 而言过于主观,但我会将其作为一个选项提交我认为这个逻辑的理想可读性:
let rec calculator list (h::t) =
if List.isEmpty h then h
elif validate list h = validate theCode list then h::(calculator list t)
else calculator list t
(假设 SS
是 F# 列表而不是 System.Collections.Generic.List
。)
这实际上不是如何实现 when
守卫问题的答案,因为 @ildjarn 适合您。
我认为库函数实际上会更好地为您服务。您正在尝试做的似乎是过滤掉未通过验证的元素,但也停止在第一个空元素上。如果你能保证你肯定想要遍历 SS
的每个元素,你可以简单地做
let calculator list = List.filter (fun s -> validate list s = validate theCode list)
如果你必须在空元素处停止,你可以定义一个函数在第一个空元素处切割列表,比如
let upToElement element list =
let rec loop acc = function
| [] -> List.rev acc
| h :: t when h = element -> List.rev acc
| h :: t -> loop (h :: acc) t
loop [] list
那你就可以了
let calculator list =
upToElement [] >> List.filter (fun s -> validate list s = validate theCode list)
我制作了一个函数,它接受一个列表和一个列表列表,return一个新的列表列表。
let rec calculator list SS =
match (List.item(0) SS) with
|[] -> []
|_ -> match (validate list (List.item(0) SS)) with
|(validate theCode list) -> List.append [(List.item(0) SS)] (calculator list (SS.[1..]))
|_ -> (calculator list (SS.[1..]))
validate 是 return 两个元组整数的函数。示例 (1,1)
list 是一个包含四个整数的列表
SS 是一个包含四个整数的列表列表
theCode 是一个包含四个整数的列表
我收到错误 "The pattern discriminator 'validate' is not defined."
也许这是一个愚蠢的问题,但 none 我越是不知道它的答案。
是否不允许在匹配表达式中使用函数作为参数。还是这里发生了完全不同的事情?
据我所知,这两个验证函数将 return 两个元组整数,因此应该能够与之匹配。
如果你的问题是如何让它编译,那么你只需要一个小的改变——函数调用本身不是一个模式,所以你需要绑定到一个值并使用 when
guard:
let rec calculator list SS =
match (List.item(0) SS) with
| [] -> []
| _ ->
match (validate list (List.item(0) SS)) with
// vvvvvvvvvv
| x when x = (validate theCode list) ->
List.append [(List.item(0) SS)] (calculator list (SS.[1..]))
| _ -> (calculator list (SS.[1..]))
但是,如果您的问题确实是“首选方法是什么”,那么虽然这对于本网站 (IMO) 而言过于主观,但我会将其作为一个选项提交我认为这个逻辑的理想可读性:
let rec calculator list (h::t) =
if List.isEmpty h then h
elif validate list h = validate theCode list then h::(calculator list t)
else calculator list t
(假设 SS
是 F# 列表而不是 System.Collections.Generic.List
。)
这实际上不是如何实现 when
守卫问题的答案,因为 @ildjarn
我认为库函数实际上会更好地为您服务。您正在尝试做的似乎是过滤掉未通过验证的元素,但也停止在第一个空元素上。如果你能保证你肯定想要遍历 SS
的每个元素,你可以简单地做
let calculator list = List.filter (fun s -> validate list s = validate theCode list)
如果你必须在空元素处停止,你可以定义一个函数在第一个空元素处切割列表,比如
let upToElement element list =
let rec loop acc = function
| [] -> List.rev acc
| h :: t when h = element -> List.rev acc
| h :: t -> loop (h :: acc) t
loop [] list
那你就可以了
let calculator list =
upToElement [] >> List.filter (fun s -> validate list s = validate theCode list)