OCaml:使用范围构建列表,其中大小由从 float 转换为 int 确定

OCaml: building a list using a range in which the size id determined by a int cast from a float

我正在尝试在 OCaml 中构建一个列表,该列表从一个函数中获取其结束范围变量,该函数 return 是一个从浮点数转换为 int 的函数:

    #require "batteries"
    #require "pa_comprehension"
    #require "core_kernel"
open Batteries
open Core_kernel

let factor_of num fact = num mod fact == 0 ;;

let limit num =  Float.to_int (floor (sqrt num) ) ;;

由于以下原因未执行此列表的填充:

Error: This expression has type int but an expression was expected of type [<向下| To ]

在(美味的)电池列表理解中:

[? List: x | x <- 0--(limit num) ; factor_of num x ?] ;;

和(稍微少一点但仍然很易读)core_kernel 列表构造函数:

List.(range 0 (limit num) |> filter ~f:( fun x -> factor_of num x) );;

我认为来自 limit num 的 return 被困在提供 Float.to_int 函数的(邪恶的)monad 中。使用 Float.int_of_float 时也会发生这种情况,类型签名相同:

utop # Float.to_int;;
- : float -> int = <fun>

那么...我如何获得 monad 的 int 'out',或者,如果这不是问题所在,那么发生了什么以及如何转换为实际的 int 这样可以用吗?

另外,有人可以给我指点一个不错的 'What the hell are these things: Monads' 教程吗?我对他们束手无策。

更新:错误不是由任何 monadic 行为(或根本不使用,事实上)引起的,而是由于中缀运算符 (mod) 的不正确使用以及其他一些怪癖我还没有完全理解的功能性思维。我不确定这个 post 是否仍然存在,但也许它是您在进入功能范式时可能犯的错误的一个例子...?

我已经找到了问题的根源。想多了又熬夜了:

该错误不是由任何 monadic 行为(或者根本不使用 monads,事实上)引起的,而是由于中缀运算符 (mod) 的不正确使用以及其他一些怪癖我还没有完全理解的功能性思维。我不确定这个 post 是否仍然存在,但也许它是您在进入功能范式时可能犯的错误的一个例子...?

帮助我解决问题的功劳归功于 Str 帮助我改变了想法。 Joe Gob 还指出了代码中的主要问题。根据我的函数所需的类型在 float 和 int 之间进行更多转换。

这是更正后的代码(deps.ml 是需求文件):

   #use "deps.ml";;
open Batteries
open Core_kernel

let factor_of num fact = num mod fact == 0 ;;

let limit num = 2 * Float.to_int (floor (sqrt num)) ;;

let factor_list_of num =
  [? List: x | x <- 1--(limit (Int.to_float num)) ; factor_of num x ?]

let sum_factors num = ( List.fold_right (+) (factor_list_of num) 0 )

let is_perfect num = sum_factors num == num
let is_abundant num = sum_factors num > num
let is_deficient num = sum_factors num < num

基本上我被Ruby宠坏了,但我强烈建议ruby爱好者学习ocaml,它的风格最接近函数式语言的ruby代码。