Functor——bind

其实在研究bind前我也一直很疑惑,我们可以延迟调用函数,却不知道如何传递当时的环境情况,绑定可以,虽然loki只提供了BindFirst,但是递归是loki还有你我都已经达成的共识。

BindFirst接受Functor,而且返回Functor,你可以想像,它一定内部对传入的Functor进行了某种转换、拷贝仰或赋值。我们来看BindFirst函数:

template     < class  Fctor >
BindFirst(
const  Fctor &  fun,typename Fctor::Param1 bound)
{
    typedef    Fctor::BoundFunctorType    Outgoing;
    
return    Outgoing(std::auto_ptr<typename Outgoing::Impl>(new BinderFirst<Fctor>(fun,bound)));
}

BindFirst只是一个助手函数,它负责创建一个新的FunctorImpl,而此处的FunctorImpl 接受一个额外的参数:Fctor::Parm1,可以想象,新的Impl一定是内部保存了这个参数,在调用的时候进行的参数传递。

和开发其他FunctorImpl一样,BinderFirst可以被轻易完成,只是你一看记住需要记录一个额外的参数。

template     < class  Incoming >
class     BinderFirst    : public  FunctorImpl < typename Incoming::ResultType,typename Incoming::Arguments::Tail >
{
    typedef Functor
<typename Incoming::ResultType,Incoming::Arguments::Tail>    Outgoing;
    typedef typename Incoming::Parm1    Bound;
    typedef typename Incoming::ResultType    ResultType;
public:
    BinderFirst(
const Incoming& fun,Bound bound)    :fun_(fun),bound_(bound){}
    
//...
    ResultType    operator()(){    return fun_(bound_);    }
    ResultType    
operator()(typename Outgoing::Parm1 p1){    return fun_(bound_,p1);    }
    ResultType    
operator()(typename Outgoing::Parm1 p1,typename Outgoing::Parm2 p2){    return fun_(bound_,p1,p2);    }
private:
    Incoming    fun_;
    Bound        bound_;
}
;

MCD里对对这段代码解释的不好,而且它的代码可能是直接拷贝loki里的东西,名称空间还在,要详细了解这部分,建议看loki代码这部分。

如你所见,BindFirst是方法,你可以在任何阶段使用它,这有别于类似typelist的编译期推到的思想,这也就是说,运行阶段的任意合法操作(编译期未知行为)都可以使用BindFirst。

int     doadd( int  a, int  b)
{
    
return    a + b;
}


int  _tmain( int  argc, _TCHAR *  argv[])
{
    Functor
<int,LOKI_TYPELIST_2(int,int)>    cmd1(doadd);
    Functor
<int,LOKI_TYPELIST_1(int)>        cmd2(BindFirst(cmd1,1));
    Functor
<int>        cmd3(BindFirst(cmd2,1));
    cout
<<cmd3()<<endl;
    
    Functor
<int>        cmd4(BindFirst(cmd2,cmd3()));
    cout
<<"cmd4() = "<<cmd4()<<endl;

    
for (int i = 0;i < 10++i)
    
{
        Functor
<int>    cmd5(BindFirst(cmd2,i * i));
        cout
<<i<<":"<<cmd5()<<endl;
    }

    
return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
函数式编程中的 `Maybe`, `Either`, `Functor` 和 `Monad` 是常见的一些概念。 `Maybe` 表示一个可能为空的值,它可以用来避免程序中的空指针异常。在 Haskell 中,`Maybe` 是一个数据类型,它有两个值:`Just a` 表示存在一个值,值为 `a`;`Nothing` 表示不存在值。在其他语言中,可以通过自定义一个 `Maybe` 类型来实现类似的功能。 `Either` 表示一个值可能是两种类型中的一种。在 Haskell 中,`Either` 是一个数据类型,它有两个参数:`Either a b` 表示值可以是类型 `a` 或 `b` 中的一种。在其他语言中,可以通过自定义一个 `Either` 类型来实现类似的功能。 `Functor` 是一个抽象概念,它表示一个能够被映射(map)的数据结构。在 Haskell 中,`Functor` 是一个类型类,它要求实现一个 `fmap` 函数,它可以将一个函数作用于一个 Functor 上。在其他语言中,可以通过实现一个 `map` 函数来实现类似的功能。 `Monad` 是一个用于处理副作用的抽象概念。在函数式编程中,副作用是指函数执行过程中对程序状态进行修改,比如 I/O 操作、异常处理等。为了避免副作用对程序的影响,函数式编程中引入了 Monad 的概念。Monad 要求实现一个 `bind` 函数,它可以将一个 Monad 的值传递给一个函数,并返回一个新的 Monad。在 Haskell 中,`Monad` 是一个类型类,它要求实现 `return` 和 `>>=` 函数。在其他语言中,可以通过自定义一个 Monad 类型来实现类似的功能。 综上所述,`Maybe`, `Either`, `Functor` 和 `Monad` 都是函数式编程中常见的一些概念,它们可以帮助程序员编写更加健壮、可维护的代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值