我是一名长期的C#开发人员并且试图抓住F#并且这样做我想做一个我需要以下内容的小项目:
是否可以使用以下行为来实现功能?注意:我知道ref
可能有可能,但我希望它更“纯粹”。
let count (x:int) (y:iny): (int -> int * int) =
??
let myCount = count 1
// --------
let myCount, value = myCount 2;; // value is now 3
let myCount, value = myCount 3;; // value is now 6
let myCount, value = myCount 1;; // value is now 7
答案 0 :(得分:7)
你提供的 type-signature 是不可能的(因为你返回一个有两个整数的元组,但显然第一个应该再次具有与count 1
本身相同的签名,这是不可能直接 - 你必须以某种方式包装它。)
但根据你的例子,我认为你的想法应该是可能的:
这是一个与你的版本略有不同的版本,但我认为你明白了这个想法:
type Counter = { value : int; update : int -> Counter }
let rec counter init =
{ value = init; update = fun upd -> counter (upd+init) }
这就是它的实际效果:
> let myCounter = counter 1;;
val myCounter : Counter = {value = 1;
update = <fun:counter@118>;}
> let myCounter = myCounter.update 2;;
val myCounter : Counter = {value = 3;
update = <fun:counter@118>;}
> let myCounter = myCounter.update 3;;
val myCounter : Counter = {value = 6;
update = <fun:counter@118>;}
> let myCounter = myCounter.update 1;;
val myCounter : Counter = {value = 7;
update = <fun:counter@118>;}
对你来说足够近了吗?
当然,如果你放弃纯粹性,你可以这样做更简单(在F#中做这样的事情确实很常见):
let counter init =
let value = ref init
fun upd ->
value := !value + upd
!value
这是你的例子
> let myCounter = counter 1;;
val myCounter : (int -> int)
> myCounter 2;;
val it : int = 3
> myCounter 3;;
val it : int = 6
> myCounter 1;;
val it : int = 7
答案 1 :(得分:0)
因为你提到&#34;纯功能&#34;我会提及&#34;州monad&#34; ...
&#34;更新&#34;它结合了更多:http://tomasp.net/blog/2014/update-monads/
做一些代码示例需要以下必要条件:将fsharpx.extras复制到为此代码制作的某个项目中。
#r @"..\packages\FSharpx.Extras.1.10.2\lib\40\FSharpx.Extras.dll"
open FSharpx.State
open System
let myCount value =
state {
let! s = getState
do! putState (s + value)
return s
}
let myNewCountWithTotalResult =
state {
let! _ = myCount 1
let! _ = myCount 2
let! _ = myCount 3
let! _ = myCount 1
return ()
}
printfn "My total with 0 as initial state is: %A" (exec myNewCountWithTotalResult 0)
//Just for the hell of it if you wanna initiate the state with something other than 0
//to get a totally different result
printfn "My total with 4 as initial state is:%A" (exec myNewCountWithTotalResult 4)
是的,我不确定自己是否理解这一点。
另外:忘记我提到了&#34; monad&#34; ; - )