【问题标题】:Write a multiline function in ocaml在ocaml中写一个多行函数
【发布时间】:2019-03-16 20:11:41
【问题描述】:

我无法理解如何在 ocaml 中编写函数,因为我只编写了不需要由 ; 分隔的多行的递归函数。

我正在尝试创建一个给定整数 n 的函数,它返回一个充满零且对角线上只有一个的矩阵,因此是一个大小为 n 的单位矩阵。
我是函数式编程和 ocaml 的新手,所以我想知道是否可以用命令式的方式编写它。 例如在 Java 中我会写:

public int[][] identity(int size) {
    int[][] matrix;
    matrix = new int[size][size];
    //fill the matrix with zeroes
    for( int i=0; i<size; i++){
        for( int j=0; j<size; j++){
            matrix[i][j] = 0;
        }
    }
    //diagonal values at 1
    for (int i=0; i<size; i++){
        matrix[i][i] = 1;
    }
    return matrix;
}

如何在 ocaml 中实现这一点?

【问题讨论】:

    标签: ocaml


    【解决方案1】:

    您可以在 ocaml 中使用基本相同的方法,如下所示:

    let identity size =
        let m = Array.make_matrix size size 0 in
        for i = 0 to size - 1 do
            m.(i).(i) <- 1;
        done;
        m
    

    ocaml 的不同之处在于您必须创建一个填充了某些东西的矩阵(在本例中为 0)。因此,将条目设置为 0 的第一个循环消失了,因为 Array.make_matrix 在内部执行此操作。没有办法初始化它。然后将对角线更改为 1。

    另一种方法是首先用正确的值初始化矩阵。你也可以这样做:

    let identity size =
      Array.init
        size
        (fun x ->
           Array.init
             size
             (fun y -> if x = y then 1 else 0))
    

    【讨论】:

    • 嘿,感谢您的回答,最后我设法做到了,但我完全忘记了为其他人发布答案。想到的第一个解决方案是第一个,但在阅读了 Array 的文档后,我找到了您发布的“功能性”解决方案。
    【解决方案2】:

    您可以以命令式的方式编写 OCaml 代码,是的。 OCaml 有矩阵(表示为数组的数组),矩阵是可变的,并且它有一个for 语句。因此,您可以编写看起来与您在 Java 中编写的代码非常相似的代码。

    然而,仅仅为了编写命令式代码而学习 OCaml 似乎是一种耻辱!

    这里有一些你可以放在一起的代码片段:

    # let m = Array.make_matrix 3 3 0;;
    val m : int array array = [|[|0; 0; 0|]; [|0; 0; 0|]; [|0; 0; 0|]|]
    
    # m.(1).(1) <- 1;;
    - : unit = ()
    
    # m;;
    - : int array array = [|[|0; 0; 0|]; [|0; 1; 0|]; [|0; 0; 0|]|]
    
    # for i = 0 to 9 do Printf.printf " %d" i done;;
     0 1 2 3 4 5 6 7 8 9- : unit = ()
    

    OCaml 中的多行函数没有什么特别之处。这是一个执行三件事的函数。你可以写在一行或多行:

    let f x =
        Printf.printf "I will now write the value of x\n";
        Printf.printf "Here is the value of x: %d\n" x;
        Printf.printf "I just wrote the value of x\n"
    

    在 OCaml 中,; 用于分隔应按顺序计算的表达式。即,在最后一个表达式之后没有;

    【讨论】:

    • 我也在想,以命令式的方式来做这件事在这门语言中并不是最好的主意,但我看不到出路。我现在看到的唯一方法是像你一样创建一个充满零的矩阵,然后创建一个只改变对角线的第二个函数。我现在没有时间写它,但我想它必须是递归的?感谢您的帮助和快速答复
    • 好吧,由于 OCaml 数组是可变的,处理数组的代码在风格上往往是命令式的。没有办法解决它。但是您可以通过调用Array.init 用很少的代码创建一个标识数组。您只需将正确的函数作为参数传递。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-04
    • 1970-01-01
    相关资源
    最近更新 更多