我理解F#中函数组合的基础知识,例如,这里描述的.
也许我错过了一些东西.在>>与<<运营商似乎已经与各功能只需要一个参数的假设定义:
> (>>);;
val it : (('a -> 'b) -> ('b -> 'c) -> 'a -> 'c) = <fun:it@214-13>
> (<<);;
val it : (('a -> 'b) -> ('c -> 'a) -> 'c -> 'b) = <fun:it@215-14>
Run Code Online (Sandbox Code Playgroud)
但是,我想做的事情如下:
let add a b = a + b
let double c = 2*c
let addAndDouble = add >> double // bad!
Run Code Online (Sandbox Code Playgroud)
但即使add输出是输入所需的类型double,也会被拒绝.
我知道我可以用一个元组参数重写add:
let add (a,b) = a + b
Run Code Online (Sandbox Code Playgroud)
或者我可以为第一个函数的每个可能的参数编写一个新的运算符: …
以下代码发送 GET 请求。这让我发疯。
let postDocRaw (url:string) (data: string) : string =
let data' : byte[] = System.Text.Encoding.ASCII.GetBytes(data);
let request = WebRequest.Create(url)
request.Method <- "POST"
request.ContentType <- "application/x-www-form-urlencoded"
request.ContentLength <- (int64) data'.Length
use wstream = request.GetRequestStream()
wstream.Write(data',0, (data'.Length))
wstream.Flush()
wstream.Close()
(*
use writer = new StreamWriter (wstream)
writer.Write(data')
writer.Flush()
writer.Close()
*)
let response = request.GetResponse()
use reader = new StreamReader(response.GetResponseStream())
let output = reader.ReadToEnd()
reader.Close()
response.Close()
request.Abort()
output
Run Code Online (Sandbox Code Playgroud)
目前我不确定是否有人曾经使用 F# 发送 HTTP POST。有没有人看过这方面的文档?
在使用一些F#(通过MonoDevelop)时,我编写了一个例程,用一个线程列出目录中的文件:
let rec loop (path:string) =
Array.append
(
path |> Directory.GetFiles
)
(
path
|> Directory.GetDirectories
|> Array.map loop
|> Array.concat
)
Run Code Online (Sandbox Code Playgroud)
然后是它的异步版本:
let rec loopPar (path:string) =
Array.append
(
path |> Directory.GetFiles
)
(
let paths = path |> Directory.GetDirectories
if paths <> [||] then
[| for p in paths -> async { return (loopPar p) } |]
|> Async.Parallel
|> Async.RunSynchronously
|> Array.concat
else
[||]
)
Run Code Online (Sandbox Code Playgroud)
在小目录上,异步版本工作正常.在更大的目录(例如,数千个目录和文件)上,异步版本似乎挂起了.我错过了什么?
我知道创建数千个线程永远不会是最有效的解决方案 - 我只有8个CPU - 但我感到困惑的是,对于较大的目录,异步函数只是没有响应(即使在半小时后).然而,它并没有明显地失败,这令我感到困惑.是否有一个耗尽的线程池?
这些线程如何实际工作?
编辑:
根据这份文件:
Mono> …
我正在使用getOpts 查看此示例,其中一部分让我感到困惑:字段标签的语法.
首先,这看起来很简单,创建数据类型并声明初始值:
data Options = Options { optVerbose :: Bool
, optInput :: IO String
, optOutput :: String -> IO ()
}
startOptions :: Options
startOptions = Options { optVerbose = False
, optInput = getContents
, optOutput = putStr
}
Run Code Online (Sandbox Code Playgroud)
然后getOpt用于浏览选项并使用foldl命令确定正在运行的程序的实际参数...然后这个让表达式让我感到沮丧:
let Options { optVerbose = verbose
, optInput = input
, optOutput = output } = opts
Run Code Online (Sandbox Code Playgroud)
布尔和功能verbose,input以及output随后在此之后使用.在我更熟悉的大多数编程语言中,这一步将被写成如下:
verbose = opts.optVerbose
input = opts.optInput …Run Code Online (Sandbox Code Playgroud)