首页 文章

F#作为匹配函数中的参数

提问于
浏览
1

我创建了一个函数,它接受一个列表和一个列表列表,并返回一个新的列表列表 .

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是一个返回两个tupled整数的函数 . 例子(1,1)

list是四个整数的列表

SS是包含四个整数的列表

theCode是四个整数的列表

我收到错误“模式鉴别器'验证'未定义 . ”

也许这是一个愚蠢的问题但是我不知道它的答案 .

是否不允许在匹配表达式中使用函数作为参数 . 或者这是完全不同的事情吗?

据我所知,两个验证函数将返回两个tupled整数,因此应该能够匹配 .

2 回答

  • 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..]))
    

    但是,如果您的问题确实是“什么是首选方法”,那么's too subjective for this site (IMO), I' ll将此作为一个选项提交,我认为这个逻辑可以理解为:

    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 . )

  • 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)
    

相关问题