【问题标题】:OCaml error filter list using higher order functions使用高阶函数的 OCaml 错误过滤器列表
【发布时间】:2015-09-22 05:55:46
【问题描述】:

所以我有这个练习:

filter (fun x -> x = 0) [(1,0);(2,1);(3,0);(4,1)];;
result int list [1;3]

所以基本上你必须将你的 x in fun 与列表中的第二个数字相匹配,如果相同,则使用第一个数字创建新列表。

我的解决方法是错误的

   let rec filter f = function
   | []->[]
   | x::l -> if f=snd x then fst x :: filter f l else [];;

当我想尝试代码时出现以下错误:

错误:此表达式的类型为 int,但预期的表达式为 类型 int -> bool

【问题讨论】:

    标签: list function types filter ocaml


    【解决方案1】:

    我无法重现您报告的问题。这是我在尝试您的代码时看到的:

    $ ocaml
            OCaml version 4.02.1
    
    # let rec filter f = function
       | []->[]
       | x::l -> if f=snd x then fst x :: filter f l else []    ;;
    val filter : 'a -> ('b * 'a) list -> 'b list = <fun>
    # filter 0 [(1,0); (2,1); (3,0)];;
    - : int list = [1]
    

    没有错误,但它得到了错误的答案。这就是我期望查看您的代码的结果。

    【讨论】:

    • 是的,你是对的,我忘了补充说 f 必须像我的例子,而不仅仅是一个数字..你可以有 "(fun x -> x != 0)" 或 "(fun x -> x > 3)" 或类似的东西,谢谢!
    • 好的,那么if f = snd x 就没有意义了。这将 f(作为一个值)与该对的第二个元素进行比较。您想将 f 作为函数调用。这看起来更像if f (snd x)
    【解决方案2】:

    你得到的错误是说编译器在某个地方期待一个int -&gt; bool函数,但你给它一个int。您收到此错误的原因是因为您有一个相等 (f = snd x),其中 f 的类型为 int -&gt; boolsnd x 的类型为 int。赋予相等性的两个参数必须是同一类型。相反,您要做的只是将f 应用于x 的第二个元素的结果进行分支,例如:

    let rec filter f = function
      | []->[]
      | x::l -> if f (snd x) then fst x :: filter f l else [];;
    

    也就是说,我建议使用模式匹配而不是fstsnd,例如:

     let rec filter f l = 
         match l with
             | [] -> []
             | (x,y)::l -> if f y then x :: filter f l else filter f l
    

    请注意,f y 将返回 bool 类型的内容,然后确定要采用哪个分支。

    【讨论】:

      【解决方案3】:

      Altough Matts 的答案是正确的。重用现有函数而不是从头开始编写特殊函数是很好的:

      [(1,0);(2,1);(3,0);(4,1)]
      |> List.filter (fun (_, x) -> x = 0)
      |> List.map fst
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-18
        • 1970-01-01
        相关资源
        最近更新 更多