2016-11-15 65 views
1

我做了一个函数,它接受一个列表和一个列表列表,并返回一个新的列表列表。F#函数作为匹配函数中的参数

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是返回两个元组intt整数的函数。例如(1,1)

名单是四个整数

SS列表中列出的四个整数

导出代码列表被四个整数

我得到的错误清单“模式鉴别器'validate'没有被定义。“

也许这是一个愚蠢的问题,但没有一个我不知道答案。

不允许在匹配表达式中使用函数作为参数。或者是在这里完全不同的东西?

就我所知,两个验证函数将返回两个元组,因此应该能够匹配。

+4

我想你想在这里上的有源图案 –

+0

*“验证是一个函数,返回两个元组int。“*假设函数验证某个输入,当输入有效时它返回什么?当输入无效时它会返回什么? –

+2

为了编译,用'|替换'|(验证代码列表) - >'| x当x =(验证代码列表) - >'。但正如@约翰·帕尔默所暗示的那样,这很简单丑陋 - 甚至'if..else'在这里也会更干净。 – ildjarn

回答

4

如果你的问题是如何得到这个编译那么你只需要一个小的变化–函数调用本身不是一个模式,所以你需要绑定到一个值,并使用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。)

+0

非常感谢你。 – Nulle

+2

只需要注意一点:通过'h :: calculator list t'将一个单独的元素添加到一个列表中比创建一个新的元素列表来添加一个列表更为常见。 –

+0

@JakeLishman:的确如此!我专注于摆脱“匹配”,并没有彻底思考剩下的问题(显然)。编辑,谢谢。 – ildjarn

4

这其实不是一个答案,如何实现when后卫的问题,因为@ildjarn answered适合您。

我想你会更好地服务于图书馆的功能。你试图做的似乎是过滤掉没有通过验证的元素,但也停止在第一个空元素。如果你能保证你一定要遍历的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) 
+0

非常感谢!我的目的是过滤掉任何不通过验证的元素。所以我一定会考虑你的List.filter解决方案! – Nulle