在纯函数式编程语言(如Haskell)中,或者只是以函数方式使用它(例如clojure); 假设你有一个整数的list/seq/enumerable(未知大小),你想要生成一个包含连续项之间差异的新list/seq/enumerable,你会怎么做?
我之前在C#中所做的是折叠列表并将状态对象保留为记录"上一个"项目的聚合值,以便您可以从当前项目对其进行差异处理.结果列表也必须进入状态对象(对于未知大小的列表,这是一个问题)
在功能上做这种事情的一般方法是什么?
谈到一些quants/hedgies,我得出的结论是,他们中的很多人似乎都在使用自制语言或OCaml执行许多任务.许多人无法回答的原因是.
我当然可以理解他们为什么不想在大多数情况下使用C++,但为什么OCaml与其他脚本语言(如Python,Ruby等)相比更适合这些用途?
Clojure的具有宏->,这需要一个数据片和一组函数,所述数据适用于第一功能,然后应用的,为下一个,的结果的结果的是到第三个,等,最后给你回到最后一个申请的结果.
我非常喜欢这个,因为它不必从应用它们的顺序向后编写函数,如下所示:(伪代码跟随)
floor (square.root (x))
Run Code Online (Sandbox Code Playgroud)
您可以按照数据流经它们的顺序编写它们:
-> x (square.root, floor)
Run Code Online (Sandbox Code Playgroud)
我的问题是,在函数式语言中是否有这个函数的标准名称,map,reduce和filter有标准名称吗?Clojure文档将其描述为"通过函数线程化数据",但我在谷歌上找不到任何东西thread.我在Haskell中写了一个简单的版本:
thread :: a -> [(a -> a)] -> a
thread x [] = x
thread x (f:fs) = thread (f x) fs
Run Code Online (Sandbox Code Playgroud)
并a -> [(a -> a)] -> a在Hoogle上搜索,但也没有找到任何东西.
在研究这个问题时,我还发现你可以使用Control.ArrowHaskell中的函数组合运算符做一个非常类似的事情,如下所示:
($2) (sin >>> cos >>> tan)
Run Code Online (Sandbox Code Playgroud)
而使用专用的高阶thread函数,你会写:
thread 2 [sin, cos, tan]
Run Code Online (Sandbox Code Playgroud)
是否第一种配方足以满足实际用途?
以下代码无法编译:
let x = "hello" in
Printf.printf x
Run Code Online (Sandbox Code Playgroud)
错误是:
Error: This expression has type string but an expression was expected of type
('a, out_channel, unit) format =
('a, out_channel, unit, unit, unit, unit) format6
Run Code Online (Sandbox Code Playgroud)
1)有人可以解释错误信息吗?
2)为什么字符串不能传递给printf?
您能否提供一个代码片段,展示如何在OCaml中使用Lua?
一个简单的例子可能是"Hello,World"变体.让OCaml提示用户输入名称.然后将该名称传递给Lua函数.让Lua打印问候语并返回名称的长度.然后让OCaml打印一条关于名称长度的消息.
例:
user @ desktop:〜$./ hello.opt
名称?用户
你好,用户.
你的名字长4个字母.
用户@桌面:〜$
[编辑]
作为一名非C程序员,我是否可以实现这一点而无需编写中间C程序来传递Lua和OCaml之间的数据?
以下是我想尝试的理论概念.不幸的是,ocaml_hello.ml的第3行需要知道如何调用lua_hello.lua中定义的函数以使代码有效.
lua_hello.lua 定义lua_hello,它打印一个参数并返回其长度.
1 function lua_hello (name)
2 print ("Hello, "..name..".")
3 return (string.len (name))
4 end
Run Code Online (Sandbox Code Playgroud)
ocaml_hello.ml OCaml提示输入名称,调用Lua函数,并打印返回值.
1 let () = print_string "Name? "; flush stdout in
2 let name = input_line stdin in
3 let len = Lua_hello.lua_hello name in
4 Printf.printf "Your name is %d letters long." len; flush stdout;;
Run Code Online (Sandbox Code Playgroud) 我最近一直在玩OCaml,并立即做了我最喜欢的事情来检查VM /编译器的开发情况,并写了一个递归程序:
let rec f i =
Printf.eprintf "i = %d\n" i;
f(i+1);;
let () =
f 0;;
Run Code Online (Sandbox Code Playgroud)
该程序按预期运行,但是,递归永远不会中断,事实上,我让这个程序运行了几次(大约30分钟),将stderr重定向到File,以避免堵塞我的终端.检查完文件后,当我注意到文件大约是7*GB*大时,我感到很震惊!
怎么会这样?OCaml没有任何递归限制吗?
ocamldebug中的调用堆栈是真正的调用堆栈,因此进行尾调用的函数不会显示在其中.这令人困惑.如何获得包含尾调用的回溯?
ocaml functional-programming stack-trace tail-call-optimization
在我的一个项目中,我必须编写HTML和JavaScript代码.我宁愿使用静态类型的语言,所以我正在评估OPA.但是,我的目标是生成静态页面的集合,所以我不关心OPA HTTP服务器和持久层.
所以这里有我的问题:是否有一种(简单的)方法在OPA中生成静态页面的集合?
我正在尝试编写一个函数,该函数返回v给定列表中传递值的索引x; -1如果没有找到.我尝试解决方案:
let rec index (x, v) =
let i = 0 in
match x with
[] -> -1
| (curr::rest) -> if(curr == v) then
i
else
succ i; (* i++ *)
index(rest, v)
;;
Run Code Online (Sandbox Code Playgroud)
这对我来说显然是错误的(每次都会返回-1),因为它会i在每次传递时重新定义.我有一些模糊的方法,在我的头脑中使用单独的功能,没有我现在可以写下来的.我知道这是所有编程中的常见模式,所以我的问题是,在OCaml中执行此操作的最佳方法是什么?
有没有理由说OCaml无法在签名中展开中间参数化类型?
例如:
(* foo.ml *)
type 'a internal = Foo of 'a
type t = string internal
Run Code Online (Sandbox Code Playgroud)
和:
(* foo.mli *)
type t = Foo of string
Run Code Online (Sandbox Code Playgroud)
给出错误.
我想这与内存表示有时可能不同的事实相关,但我想知道在向OCaml错误跟踪器提交错误报告之前是否有更深层次的原因...
我在OCaml中的列表遇到问题.我读过冲突的陈述,说明列表是否可以在运行时修改.cons运算符可以在运行时使用吗?
另外,为什么杜宾犬(见下文)被允许列入吉娃娃名单?如何将另一个奇瓦瓦加入到列表中(如最后一行所尝试的那样)?
class virtual dog =
object
method virtual bark : unit
end;;
class chihuahua =
object
inherit dog
method bark = Printf.printf "Yip!"
end;;
class doberman =
object
inherit dog
method bark = Printf.printf "Roar!"
end;;
let c1 = new chihuahua;;
let c2 = new chihuahua;;
let c3 = new chihuahua;;
let d1 = new doberman;;
let arrayOfDogs = [c1;c2;d1];;
arrayOfDogs :: c3;;
Run Code Online (Sandbox Code Playgroud)