理解绑定函数

时间:2015-12-11 23:04:08

标签: c swift haskell functional-programming monads

在这个article中,作者使用这个例子解释了monad(我猜测使用了Haskell):

  

bind f'::(Float,String) - > (浮点型,字符串)

     

暗示

     

bind ::(Float - >(Float,String)) - > ((Float,String) - >   (浮点型,字符串))

然后继续要求实现函数bind并提供解决方案:

bind f' (gx,gs) = let (fx,fs) = f' gx in (fx,gs++fs)

我在理解解决方案时遇到了问题。这在C或Swift中会是什么样的?

我已经尽可能地实现了这个例子而且我坚持实现bind:

let f: Float -> Float = { value in return 2 * value }
let g: Float -> Float = { value in return 10 + value }

let ff: Float -> (Float, String) = { value in return (f(value), "f called") }
let gg: Float -> (Float, String) = { value in return (g(value), "f called") }

3 个答案:

答案 0 :(得分:3)

在C ++中,我认为它看起来像这样:

#include <functional>
#include <string>
#include <utility>

using P = std::pair<float, std::string>;
using FP = std::function<P(P)>;

FP mbind(std::function<P(float)> f) {
    return [f](P in) {
        auto && res = f(in.first);
        return {res.first, in.second + res.second};
    };
}

在C中你可以通过存储函数指针来做类似的事情,尽管调用语法必须更加冗长,因为你需要明确地传递状态。

答案 1 :(得分:2)

在Swift中,也许是这样的:

let bind: (Float -> (Float, String)) -> ((Float, String) -> (Float, String)) = { 
    lhs in

    return { 
        rhs in

        let result = lhs(rhs.0)
        return (result.0, "\(result.1); \(rhs.1)" )
    }
}

答案 2 :(得分:0)

这是Writer monad的bind。该monad的bind函数应该做两件事:

  1. 使用Float值执行计算。

  2. 更新现有日志(String值)。

  3. 最初,您有一个元组(oldFloat,oldString),并希望向此元组应用类型为Float -> (Float,String)的函数。

    您的函数从元组oldFloat获取(oldFloat,oldString)值并返回元组(newFloat,newString)

    您对bind功能的期望是什么?我想你想要一个包含newFloat和更新日志oldString ++ new string的元组,对吗?以下是对它的严格执行:

    bind f (oldFloat,oldString) =
        -- apply function f to oldFloat from tuple (oldFloat,oldString) 
        -- to get a new tuple (newFloat,newString)
        let (newFloat,newString) = f oldFloat
        -- you want from your bind function to get a tuple containing 
        -- a newFloat and a newString added to oldString
        in (newFloat, oldString ++ newString)