F#中的捕获计数

时间:2015-08-18 04:32:10

标签: f# capture

我是一名长期的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

2 个答案:

答案 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; ; - )