标签: computation-expression

在学术用途之外的延续monad是否有真实的适用性?

(后来的访问者:这个问题的两个答案都给出了很好的见解,如果你感兴趣的话,你应该把它们都读出来,我只能把它作为SO的限制除外)

从我在网上找到的关于延续monad的所有讨论,他们要么提到它如何与一些琐碎的例子一起使用,要么他们解释它是一个基本的构建块,因为在这篇关于所有monad母亲的文章是延续monad.

我想知道是否有适用范围.我的意思是,在continuation monad中包装递归函数或相互递归是否有意义?它有助于提高可读性吗?

这是从这篇SO帖子中获取的延续模式的F#版本:

type ContinuationMonad() =
    member this.Bind (m, f) = fun c -> m (fun a -> f a c)
    member this.Return x = fun k -> k x

let cont = ContinuationMonad()
Run Code Online (Sandbox Code Playgroud)

仅仅是为了学术兴趣,例如帮助理解monad或计算构建者?或者是否存在一些真实的适用性,增加了类型安全性,还是避免了难以解决的典型编程问题?

即,来自Ryan Riley的call/cc延续monad表明处理异常很复杂,但它没有解释它试图解决的问题,并且示例没有说明为什么它需要特定的monad.不可否认,我只是不明白它的作用,但它可能是一个宝库!

(注意:我对理解延续monad是如何工作不感兴趣,我认为我对它有一个很好的掌握,我只是看不出它解决了什么编程问题.)

monads f# haskell computation-expression continuation-passing

12
推荐指数
2
解决办法
789
查看次数

如何更改Rx Builder实现以修复堆栈溢出异常?

我正在尝试使用Rx Builder在F#Computation Expression语法中使用Reactive Extension.如何修复它以使它不会破坏堆栈?像下面的Seq示例一样.是否有任何计划提供RxBuilder的实现作为Reactive Extensions的一部分或作为.NET Framework未来版本的一部分?

open System
open System.Linq
open System.Reactive.Linq

type rxBuilder() =    
    member this.Delay f = Observable.Defer f
    member this.Combine (xs: IObservable<_>, ys : IObservable<_>) = 
        Observable.merge xs ys      
    member this.Yield x = Observable.Return x
    member this.YieldFrom (xs:IObservable<_>) = xs

let rx = rxBuilder()

let rec f x = seq { yield x 
                    yield! f (x + 1) }

let rec g x = rx { yield x 
                    yield! g (x + 1) }


//do f 5 …
Run Code Online (Sandbox Code Playgroud)

f# computation-expression system.reactive

11
推荐指数
2
解决办法
1438
查看次数

如何在计算构建器中实现延迟?

这是我到目前为止:

type Maybe<'a> = option<'a>

let succeed x = Some(x)

let fail = None

let bind rest p =
    match p with
        | None -> fail
        | Some r -> rest r

let rec whileLoop cond body =
    if cond() then
        match body() with
        | Some() ->
            whileLoop cond body
        | None ->
            fail
    else
        succeed()

let forLoop (xs : 'T seq) f =
    using (xs.GetEnumerator()) (fun it ->
            whileLoop
                (fun () -> it.MoveNext())
                (fun () -> it.Current |> f) …
Run Code Online (Sandbox Code Playgroud)

f# computation-expression

10
推荐指数
2
解决办法
1534
查看次数

StackOverflow在continuation monad中

使用以下continuation monad:

type ContinuationMonad() =
    member this.Bind (m, f) = fun c -> m (fun a -> f a c)
    member this.Return x = fun k -> k x

let cont = ContinuationMonad()
Run Code Online (Sandbox Code Playgroud)

我不明白为什么以下给我一个堆栈溢出:

let map f xs =
    let rec map xs =
        cont {
            match xs with
            | [] -> return []
            | x :: xs ->
                let! xs = map xs
                return f x :: xs
        }
    map xs id;;

let q = [1..100000] |> map ((+) …
Run Code Online (Sandbox Code Playgroud)

monads f# computation-expression

10
推荐指数
1
解决办法
827
查看次数

在计算表达式中为if..then构造的else分支调用Zero后面的直觉

计算表达式中方法的msdn文档说明了这Zero一点

在计算表达式中调用表达式的空else分支if...then.

假设我们正在使用一个identity没有Zero定义的计算构建器.

let IdentityBuilder() = 
    member this.Bind(i, f) = f i
    member this.Return(i) = i

let identity = new IdentityBuilder()
Run Code Online (Sandbox Code Playgroud)

允许使用以下代码

identity {
    printf "Hello World"
    return 1
}
Run Code Online (Sandbox Code Playgroud)

但是,不允许使用以下代码,并且编译器错误会失败

仅当计算表达式构建器定义"零"方法时,才可以使用此控件构造

identity {
    if true then printf "Hello World"
    return 1
}
Run Code Online (Sandbox Code Playgroud)

为什么编译坚持呼吁Zeroelse分支?这背后的直觉是什么?

monads f# computation-expression

10
推荐指数
1
解决办法
235
查看次数

(怎么样)我可以使这个monadic绑定尾递归?

我有这个名为Desync的monad -

[<AutoOpen>]
module DesyncModule =

    /// The Desync monad. Allows the user to define in a sequential style an operation that spans
    /// across a bounded number of events. Span is bounded because I've yet to figure out how to
    /// make Desync implementation tail-recursive (see note about unbounded recursion in bind). And
    /// frankly, I'm not sure if there is a tail-recursive implementation of it...
    type [<NoComparison; NoEquality>] Desync<'e, 's, 'a> =
        Desync of ('s -> 's * …
Run Code Online (Sandbox Code Playgroud)

monads f# tail-recursion computation-expression

10
推荐指数
1
解决办法
384
查看次数

在自定义计算表达式中实现绑定

我试图通过实现我自己的一个来学习更多关于F#的计算表达式.但是,我遇到了与该Bind方法有关的绊脚石.这是我到目前为止所得到的:

type public op<'a> = Op of ('a list -> 'a list)

let inline (>>) (Op a) (Op b) = Op (a >> b)

module Op =
    let id = Op id
    let bind (b : 'b -> op<'a>) (v : 'b) = b v
    let call (Op f) = f
    let push v = Op (fun t -> v :: t)
    // .. snip  ..

type OpBuilder() =
    member __.Bind (v, b) = Op.bind b v
    member …
Run Code Online (Sandbox Code Playgroud)

.net f# computation-expression

9
推荐指数
2
解决办法
177
查看次数

如何在catch-context中重新抛出异常时保持堆栈跟踪?

TL; DR:如何在以后引发先前捕获的异常,同时保留原始异常的堆栈跟踪.

因为我认为这对Resultmonad或计算表达式很有用,尤其是 因为该模式通常用于包装异常而不抛出异常,所以这里有一个很好的例子:

type Result<'TResult, 'TError> =
    | Success of 'TResult
    | Fail of 'TError

module Result =
    let bind f = 
        function
        | Success v -> f v
        | Fail e -> Fail e

    let create v = Success v

    let retnFrom v = v

    type ResultBuilder () =
        member __.Bind (m , f) = bind f m
        member __.Return (v) = create v
        member __.ReturnFrom (v) = retnFrom v
        member __.Delay (f) = f
        member …
Run Code Online (Sandbox Code Playgroud)

monads f# try-catch computation-expression

9
推荐指数
1
解决办法
896
查看次数

异步计算不会捕获OperationCancelledException

我正在尝试向URL发出异步Web请求,如果请求耗时太长,将返回该URL.我正在使用F#异步工作流和System.Net.Http库来执行此操作.

但是,我无法捕获async工作流中System.Net.Http库引发的Task/OperationCancelledExceptions .相反,异常是在Async.RunSynchronously方法中引发的,如此堆栈跟踪中所示:

> System.OperationCanceledException: The operation was canceled.    at
> Microsoft.FSharp.Control.AsyncBuilderImpl.commit[a](Result`1 res)   
> at
> Microsoft.FSharp.Control.CancellationTokenOps.RunSynchronously[a](CancellationToken
> token, FSharpAsync`1 computation, FSharpOption`1 timeout)    at
> Microsoft.FSharp.Control.FSharpAsync.RunSynchronously[T](FSharpAsync`1
> computation, FSharpOption`1 timeout, FSharpOption`1 cancellationToken)
> at <StartupCode$FSI_0004>.$FSI_0004.main@()
Run Code Online (Sandbox Code Playgroud)

代码:

#r "System.Net.Http"

open System.Net.Http
open System

let readGoogle () = async {
    try
        let request = new HttpRequestMessage(HttpMethod.Get, "https://google.co.uk")
        let client = new HttpClient()
        client.Timeout <- TimeSpan.FromSeconds(0.01) //intentionally low to always fail in this example
        let! response = client.SendAsync(request, HttpCompletionOption.ResponseContentRead) |> Async.AwaitTask …
Run Code Online (Sandbox Code Playgroud)

f# async-workflow task-parallel-library computation-expression

8
推荐指数
1
解决办法
461
查看次数

F# 说值未在计算表达式中定义

我一直在研究带有 F# 计算表达式的 State Monad,我也在尝试利用自定义操作。我得到了一些没有意义的奇怪行为。编译器报告一个值在上面两行声明时不存在。

type State<'a, 's> = ('s -> 'a * 's)

module State =
    // Explicit
    // let result x : State<'a, 's> = fun s -> x, s
    // Less explicit but works better with other, existing functions:
    let result x s = 
        x, s

    let bind (f:'a -> State<'b, 's>) (m:State<'a, 's>) : State<'b, 's> =
        // return a function that takes the state
        fun s ->
            // Get the value and next state from …
Run Code Online (Sandbox Code Playgroud)

monads f# computation-expression

8
推荐指数
1
解决办法
339
查看次数