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代码。
我正在尝试在 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代码。